@loaders.gl/worker-utils 4.4.0-alpha.2 → 4.4.0-alpha.9

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 (71) hide show
  1. package/dist/index.cjs +47 -11
  2. package/dist/index.cjs.map +4 -4
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/async-queue/async-queue.js +1 -0
  8. package/dist/lib/async-queue/async-queue.js.map +1 -0
  9. package/dist/lib/env-utils/assert.js +1 -0
  10. package/dist/lib/env-utils/assert.js.map +1 -0
  11. package/dist/lib/env-utils/globals.js +1 -0
  12. package/dist/lib/env-utils/globals.js.map +1 -0
  13. package/dist/lib/env-utils/version.d.ts.map +1 -1
  14. package/dist/lib/env-utils/version.js +5 -2
  15. package/dist/lib/env-utils/version.js.map +1 -0
  16. package/dist/lib/library-utils/library-utils.d.ts +8 -2
  17. package/dist/lib/library-utils/library-utils.d.ts.map +1 -1
  18. package/dist/lib/library-utils/library-utils.js +62 -30
  19. package/dist/lib/library-utils/library-utils.js.map +1 -0
  20. package/dist/lib/node/worker_threads-browser.js +1 -0
  21. package/dist/lib/node/worker_threads-browser.js.map +1 -0
  22. package/dist/lib/node/worker_threads.js +1 -0
  23. package/dist/lib/node/worker_threads.js.map +1 -0
  24. package/dist/lib/npm-tag.js +1 -0
  25. package/dist/lib/npm-tag.js.map +1 -0
  26. package/dist/lib/process-utils/child-process-proxy.d.ts +3 -2
  27. package/dist/lib/process-utils/child-process-proxy.d.ts.map +1 -1
  28. package/dist/lib/process-utils/child-process-proxy.js +9 -5
  29. package/dist/lib/process-utils/child-process-proxy.js.map +1 -0
  30. package/dist/lib/process-utils/process-utils.js +1 -0
  31. package/dist/lib/process-utils/process-utils.js.map +1 -0
  32. package/dist/lib/worker-api/create-worker.js +1 -0
  33. package/dist/lib/worker-api/create-worker.js.map +1 -0
  34. package/dist/lib/worker-api/get-worker-url.d.ts.map +1 -1
  35. package/dist/lib/worker-api/get-worker-url.js +3 -1
  36. package/dist/lib/worker-api/get-worker-url.js.map +1 -0
  37. package/dist/lib/worker-api/process-on-worker.js +1 -0
  38. package/dist/lib/worker-api/process-on-worker.js.map +1 -0
  39. package/dist/lib/worker-api/validate-worker-version.js +1 -0
  40. package/dist/lib/worker-api/validate-worker-version.js.map +1 -0
  41. package/dist/lib/worker-farm/worker-body.js +1 -0
  42. package/dist/lib/worker-farm/worker-body.js.map +1 -0
  43. package/dist/lib/worker-farm/worker-farm.js +1 -0
  44. package/dist/lib/worker-farm/worker-farm.js.map +1 -0
  45. package/dist/lib/worker-farm/worker-job.js +1 -0
  46. package/dist/lib/worker-farm/worker-job.js.map +1 -0
  47. package/dist/lib/worker-farm/worker-pool.js +1 -0
  48. package/dist/lib/worker-farm/worker-pool.js.map +1 -0
  49. package/dist/lib/worker-farm/worker-thread.d.ts.map +1 -1
  50. package/dist/lib/worker-farm/worker-thread.js +4 -1
  51. package/dist/lib/worker-farm/worker-thread.js.map +1 -0
  52. package/dist/lib/worker-utils/get-loadable-worker-url.js +1 -0
  53. package/dist/lib/worker-utils/get-loadable-worker-url.js.map +1 -0
  54. package/dist/lib/worker-utils/get-transfer-list.js +1 -0
  55. package/dist/lib/worker-utils/get-transfer-list.js.map +1 -0
  56. package/dist/lib/worker-utils/remove-nontransferable-options.js +1 -0
  57. package/dist/lib/worker-utils/remove-nontransferable-options.js.map +1 -0
  58. package/dist/null-worker.d.ts +2 -0
  59. package/dist/null-worker.d.ts.map +1 -0
  60. package/dist/types.js +1 -0
  61. package/dist/types.js.map +1 -0
  62. package/dist/workers/null-worker.js +1 -0
  63. package/dist/workers/null-worker.js.map +1 -0
  64. package/package.json +8 -2
  65. package/src/index.ts +5 -1
  66. package/src/lib/env-utils/version.ts +4 -1
  67. package/src/lib/library-utils/library-utils.ts +71 -34
  68. package/src/lib/process-utils/child-process-proxy.ts +16 -7
  69. package/src/lib/worker-api/get-worker-url.ts +2 -1
  70. package/src/lib/worker-farm/worker-thread.ts +3 -1
  71. package/src/null-worker.ts +6 -0
package/src/index.ts CHANGED
@@ -40,7 +40,11 @@ export {validateWorkerVersion} from './lib/worker-api/validate-worker-version';
40
40
  export {getTransferList, getTransferListForWriter} from './lib/worker-utils/get-transfer-list';
41
41
 
42
42
  // LIBRARY UTILS
43
- export {getLibraryUrl, loadLibrary} from './lib/library-utils/library-utils';
43
+ export {
44
+ getLibraryUrl,
45
+ loadLibrary,
46
+ type LoadLibraryOptions
47
+ } from './lib/library-utils/library-utils';
44
48
 
45
49
  // PARSER UTILS
46
50
  export {default as AsyncQueue} from './lib/async-queue/async-queue';
@@ -7,16 +7,19 @@ import {NPM_TAG} from '../npm-tag';
7
7
  // Version constant cannot be imported, it needs to correspond to the build version of **this** module.
8
8
  declare let __VERSION__: string;
9
9
 
10
+ let warningIssued = false;
11
+
10
12
  function getVersion() {
11
13
  if (!globalThis._loadersgl_?.version) {
12
14
  globalThis._loadersgl_ = globalThis._loadersgl_ || {};
13
15
  // __VERSION__ is injected by babel-plugin-version-inline
14
- if (typeof __VERSION__ === 'undefined') {
16
+ if (typeof __VERSION__ === 'undefined' && !warningIssued) {
15
17
  // eslint-disable-next-line
16
18
  console.warn(
17
19
  'loaders.gl: The __VERSION__ variable is not injected using babel plugin. Latest unstable workers would be fetched from the CDN.'
18
20
  );
19
21
  globalThis._loadersgl_.version = NPM_TAG;
22
+ warningIssued = true;
20
23
  } else {
21
24
  globalThis._loadersgl_.version = __VERSION__;
22
25
  }
@@ -7,6 +7,14 @@ import {isBrowser, isWorker} from '../env-utils/globals';
7
7
  import {assert} from '../env-utils/assert';
8
8
  import {VERSION} from '../env-utils/version';
9
9
 
10
+ export type LoadLibraryOptions<ModulesT extends Record<string, any> = Record<string, any>> = {
11
+ useLocalLibraries?: boolean;
12
+ CDN?: string | null;
13
+ modules?: ModulesT;
14
+ // Core must not be supplied
15
+ core?: never;
16
+ };
17
+
10
18
  const loadLibraryPromises: Record<string, Promise<any>> = {}; // promises
11
19
 
12
20
  /**
@@ -27,7 +35,7 @@ const loadLibraryPromises: Record<string, Promise<any>> = {}; // promises
27
35
  export async function loadLibrary(
28
36
  libraryUrl: string,
29
37
  moduleName: string | null = null,
30
- options: object = {},
38
+ options: LoadLibraryOptions = {},
31
39
  libraryName: string | null = null
32
40
  ): Promise<any> {
33
41
  if (moduleName) {
@@ -45,9 +53,13 @@ export async function loadLibrary(
45
53
  export function getLibraryUrl(
46
54
  library: string,
47
55
  moduleName?: string,
48
- options: any = {},
56
+ options: LoadLibraryOptions = {},
49
57
  libraryName: string | null = null
50
58
  ): string {
59
+ if (options?.core) {
60
+ throw new Error('loadLibrary: options.core must be pre-normalized');
61
+ }
62
+
51
63
  // Check if already a URL
52
64
  if (!options.useLocalLibraries && library.startsWith('http')) {
53
65
  return library;
@@ -94,10 +106,21 @@ async function loadLibraryFromFile(libraryUrl: string): Promise<any> {
94
106
  // } catch (error) {
95
107
  // console.error(error);
96
108
  // }
109
+ const {requireFromFile} = globalThis.loaders || {};
97
110
  try {
98
- const {requireFromFile} = globalThis.loaders || {};
99
- return await requireFromFile?.(libraryUrl);
111
+ const result = await requireFromFile?.(libraryUrl);
112
+ if (result || !libraryUrl.includes('/dist/libs/')) {
113
+ return result;
114
+ }
115
+ return await requireFromFile?.(libraryUrl.replace('/dist/libs/', '/src/libs/'));
100
116
  } catch (error) {
117
+ if (libraryUrl.includes('/dist/libs/')) {
118
+ try {
119
+ return await requireFromFile?.(libraryUrl.replace('/dist/libs/', '/src/libs/'));
120
+ } catch {
121
+ // ignore
122
+ }
123
+ }
101
124
  console.error(error); // eslint-disable-line no-console
102
125
  return null;
103
126
  }
@@ -114,19 +137,6 @@ async function loadLibraryFromFile(libraryUrl: string): Promise<any> {
114
137
  return loadLibraryFromString(scriptSource, libraryUrl);
115
138
  }
116
139
 
117
- /*
118
- async function loadScriptFromFile(libraryUrl) {
119
- const script = document.createElement('script');
120
- script.src = libraryUrl;
121
- return await new Promise((resolve, reject) => {
122
- script.onload = data => {
123
- resolve(data);
124
- };
125
- script.onerror = reject;
126
- });
127
- }
128
- */
129
-
130
140
  // TODO - Needs security audit...
131
141
  // - Raw eval call
132
142
  // - Potentially bypasses CORS
@@ -158,28 +168,20 @@ function loadLibraryFromString(scriptSource: string, id: string): null | any {
158
168
  return null;
159
169
  }
160
170
 
161
- // TODO - technique for module injection into worker, from THREE.DracoLoader...
162
- /*
163
- function combineWorkerWithLibrary(worker, jsContent) {
164
- var fn = wWorker.toString();
165
- var body = [
166
- '// injected',
167
- jsContent,
168
- '',
169
- '// worker',
170
- fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))
171
- ].join('\n');
172
- this.workerSourceURL = URL.createObjectURL(new Blob([body]));
173
- }
174
- */
175
-
176
171
  async function loadAsArrayBuffer(url: string): Promise<ArrayBuffer> {
177
172
  const {readFileAsArrayBuffer} = globalThis.loaders || {};
178
173
  if (isBrowser || !readFileAsArrayBuffer || url.startsWith('http')) {
179
174
  const response = await fetch(url);
180
175
  return await response.arrayBuffer();
181
176
  }
182
- return await readFileAsArrayBuffer(url);
177
+ try {
178
+ return await readFileAsArrayBuffer(url);
179
+ } catch {
180
+ if (url.includes('/dist/libs/')) {
181
+ return await readFileAsArrayBuffer(url.replace('/dist/libs/', '/src/libs/'));
182
+ }
183
+ throw new Error(`Failed to load ArrayBuffer from ${url}`);
184
+ }
183
185
  }
184
186
 
185
187
  /**
@@ -193,5 +195,40 @@ async function loadAsText(url: string): Promise<string> {
193
195
  const response = await fetch(url);
194
196
  return await response.text();
195
197
  }
196
- return await readFileAsText(url);
198
+ try {
199
+ return await readFileAsText(url);
200
+ } catch {
201
+ if (url.includes('/dist/libs/')) {
202
+ return await readFileAsText(url.replace('/dist/libs/', '/src/libs/'));
203
+ }
204
+ throw new Error(`Failed to load text from ${url}`);
205
+ }
206
+ }
207
+
208
+ /*
209
+ async function loadScriptFromFile(libraryUrl) {
210
+ const script = document.createElement('script');
211
+ script.src = libraryUrl;
212
+ return await new Promise((resolve, reject) => {
213
+ script.onload = data => {
214
+ resolve(data);
215
+ };
216
+ script.onerror = reject;
217
+ });
197
218
  }
219
+ */
220
+
221
+ // TODO - technique for module injection into worker, from THREE.DracoLoader...
222
+ /*
223
+ function combineWorkerWithLibrary(worker, jsContent) {
224
+ var fn = wWorker.toString();
225
+ var body = [
226
+ '// injected',
227
+ jsContent,
228
+ '',
229
+ '// worker',
230
+ fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))
231
+ ].join('\n');
232
+ this.workerSourceURL = URL.createObjectURL(new Blob([body]));
233
+ }
234
+ */
@@ -3,12 +3,19 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  /* eslint-disable no-console */
6
- // Avoid using named imports for Node builtins to help with "empty" resolution
7
- // for bundlers targeting browser environments. Access imports & types
8
- // through the `ChildProcess` object (e.g. `ChildProcess.spawn`, `ChildProcess.ChildProcess`).
9
- import * as ChildProcess from 'child_process';
10
6
  import {getAvailablePort} from './process-utils';
11
7
 
8
+ type NodeChildProcess = import('child_process').ChildProcess;
9
+ type SpawnOptions = import('child_process').SpawnOptions;
10
+
11
+ async function getChildProcessModule(): Promise<typeof import('child_process')> {
12
+ if (typeof process === 'undefined' || !process.versions?.node) {
13
+ throw new Error('ChildProcessProxy is only available in Node.js environments');
14
+ }
15
+
16
+ return await import('child_process');
17
+ }
18
+
12
19
  export type ChildProcessProxyProps = {
13
20
  command: string;
14
21
  arguments: string[];
@@ -22,7 +29,7 @@ export type ChildProcessProxyProps = {
22
29
  /** wait: 0 - infinity */
23
30
  wait?: number;
24
31
  /** Options passed on to Node'.js `spawn` */
25
- spawn?: ChildProcess.SpawnOptions;
32
+ spawn?: SpawnOptions;
26
33
  /** Should proceed if stderr stream recieved data */
27
34
  ignoreStderr?: boolean;
28
35
  /** Callback when the */
@@ -48,7 +55,7 @@ const DEFAULT_PROPS: ChildProcessProxyProps = {
48
55
  export default class ChildProcessProxy {
49
56
  id: string;
50
57
  props: ChildProcessProxyProps = {...DEFAULT_PROPS};
51
- private childProcess: ChildProcess.ChildProcess | null = null;
58
+ private childProcess: NodeChildProcess | null = null;
52
59
  private port: number = 0;
53
60
  private successTimer?: any; // NodeJS.Timeout;
54
61
 
@@ -62,6 +69,8 @@ export default class ChildProcessProxy {
62
69
  props = {...DEFAULT_PROPS, ...props};
63
70
  this.props = props;
64
71
 
72
+ const childProcessModule = await getChildProcessModule();
73
+
65
74
  const args = [...props.arguments];
66
75
 
67
76
  // If portArg is set, we can look up an available port
@@ -83,7 +92,7 @@ export default class ChildProcessProxy {
83
92
  });
84
93
 
85
94
  console.log(`Spawning ${props.command} ${props.arguments.join(' ')}`);
86
- const childProcess = ChildProcess.spawn(props.command, args, props.spawn);
95
+ const childProcess = childProcessModule.spawn(props.command, args, props.spawn);
87
96
  this.childProcess = childProcess;
88
97
 
89
98
  childProcess.stdout.on('data', (data) => {
@@ -46,7 +46,8 @@ export function getWorkerURL(worker: WorkerObject, options: WorkerOptions = {}):
46
46
 
47
47
  // If URL is test, generate local loaders.gl url
48
48
  // @ts-ignore _workerType
49
- if (options._workerType === 'test') {
49
+ const workerType = (options as any)._workerType || (options as any)?.core?._workerType;
50
+ if (workerType === 'test') {
50
51
  if (isBrowser) {
51
52
  url = `modules/${worker.module}/dist/${workerFile}`;
52
53
  } else {
@@ -134,8 +134,10 @@ export default class WorkerThread {
134
134
  // Make sure relative URLs start with './'
135
135
  const absolute = this.url.includes(':/') || this.url.startsWith('/');
136
136
  const url = absolute ? this.url : `./${this.url}`;
137
+ const type = this.url.endsWith('.ts') || this.url.endsWith('.mjs') ? 'module' : 'commonjs';
137
138
  // console.log('Starting work from', url);
138
- worker = new NodeWorker(url, {eval: false});
139
+ // @ts-expect-error TODO - looks like type argmument is missing in @types/node
140
+ worker = new NodeWorker(url, {eval: false, type});
139
141
  } else if (this.source) {
140
142
  worker = new NodeWorker(this.source, {eval: true});
141
143
  } else {
@@ -0,0 +1,6 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ // Classic-worker entrypoint that lazily loads the ESM worker implementation.
6
+ import(new URL('./workers/null-worker.js', import.meta.url).toString());