bare-module-traverse 1.2.6 → 1.3.0

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/README.md CHANGED
@@ -10,36 +10,44 @@ npm i bare-module-traverse
10
10
 
11
11
  For synchronous traversal:
12
12
 
13
- ``` js
13
+ ```js
14
14
  const traverse = require('bare-module-traverse')
15
15
 
16
- function readModule (url) {
16
+ function readModule(url) {
17
17
  // Read `url` if it exists, otherwise `null`
18
18
  }
19
19
 
20
- function * listPrefix (url) {
20
+ function* listPrefix(url) {
21
21
  // Yield URLs that have `url` as a prefix. The list may be empty.
22
22
  }
23
23
 
24
- for (const dependency of traverse(new URL('file:///directory/file.js'), readModule, listPrefix)) {
24
+ for (const dependency of traverse(
25
+ new URL('file:///directory/file.js'),
26
+ readModule,
27
+ listPrefix
28
+ )) {
25
29
  console.log(dependency)
26
30
  }
27
31
  ```
28
32
 
29
33
  For asynchronous traversal:
30
34
 
31
- ``` js
35
+ ```js
32
36
  const traverse = require('bare-module-traverse')
33
37
 
34
- async function readModule (url) {
38
+ async function readModule(url) {
35
39
  // Read `url` if it exists, otherwise `null`
36
40
  }
37
41
 
38
- async function * listPrefix (url) {
42
+ async function* listPrefix(url) {
39
43
  // Yield URLs that have `url` as a prefix. The list may be empty.
40
44
  }
41
45
 
42
- for await (const dependency of traverse(new URL('file:///directory/file.js'), readModule, listPrefix)) {
46
+ for await (const dependency of traverse(
47
+ new URL('file:///directory/file.js'),
48
+ readModule,
49
+ listPrefix
50
+ )) {
43
51
  console.log(dependency)
44
52
  }
45
53
  ```
@@ -53,7 +61,7 @@ Traverse the module graph rooted at `url`, which must be a WHATWG `URL` instance
53
61
  Options include:
54
62
 
55
63
  ```js
56
- {
64
+ options = {
57
65
  resolve: resolve.default
58
66
  }
59
67
  ```
@@ -65,7 +73,7 @@ Options supported by <https://github.com/holepunchto/bare-module-resolve> and <h
65
73
  Synchronously iterate the module graph. Each yielded dependency has the following shape:
66
74
 
67
75
  ```js
68
- {
76
+ dependency = {
69
77
  url: URL,
70
78
  source: 'string' | Buffer, // Source as returned by `readModule()`
71
79
  imports: {
@@ -80,6 +88,8 @@ Asynchronously iterate the module graph. If `readModule` returns a promise or `l
80
88
 
81
89
  ### Resolution
82
90
 
91
+ Module and addon resolution is configurable by providing a resolver function. A resolver function is a generator function that yields values matching the shapes defined by <https://github.com/holepunchto/bare-module-resolve#algorithm>. Several resolvers are provided out of the box to support the most common use cases.
92
+
83
93
  #### `resolve.module`
84
94
 
85
95
  Convenience export from <https://github.com/holepunchto/bare-module-resolve>.
@@ -94,15 +104,73 @@ The default resolver, which simply forwards to <https://github.com/holepunchto/b
94
104
 
95
105
  #### `resolve.bare`
96
106
 
97
- The Bare resolver, which matches the options used by the Bare module system.
107
+ The Bare resolver, which matches the options used by the Bare module system. The resolver accepts the following additional options:
108
+
109
+ ```js
110
+ options = {
111
+ platform: Bare.platform,
112
+ arch: Bare.arch,
113
+ simulator: false,
114
+ host: `${platform}-${arch}${simulator ? '-simulator' : ''}`,
115
+ target: [host]
116
+ }
117
+ ```
118
+
119
+ For single target traversal it is sufficient to pass `platform`, `arch`, `simulator`, and/or `host`. For multi target target traversal pass a list of `target` identifiers instead.
98
120
 
99
121
  #### `resolve.node`
100
122
 
101
- The Node.js resolver, which matches the options used by the Node.js module system.
123
+ The Node.js resolver, which matches the options used by the Node.js module system. The resolver accepts the following additional options:
124
+
125
+ ```js
126
+ options = {
127
+ platform: process.platform,
128
+ arch: process.arch,
129
+ simulator: false,
130
+ host: `${platform}-${arch}${simulator ? '-simulator' : ''}`,
131
+ target: [host]
132
+ }
133
+ ```
134
+
135
+ For single target traversal it is sufficient to pass `platform`, `arch`, `simulator`, and/or `host`. For multi target target traversal pass a list of `target` identifiers instead.
102
136
 
103
137
  ### Algorithm
104
138
 
105
- The following generator functions implement the traversal algorithm. To drive the generator functions, a loop like the following can be used:
139
+ The following generator functions implement the traversal algorithm. The yielded values have the following shape:
140
+
141
+ **Source module**
142
+
143
+ ```js
144
+ next.value = {
145
+ module: URL
146
+ }
147
+ ```
148
+
149
+ **File prefix**
150
+
151
+ ```js
152
+ next.value = {
153
+ prefix: URL
154
+ }
155
+ ```
156
+
157
+ **Dependency subgraph**
158
+
159
+ ```js
160
+ next.value = {
161
+ children: URL
162
+ }
163
+ ```
164
+
165
+ **Dependency node**
166
+
167
+ ```js
168
+ next.value = {
169
+ dependency: URL
170
+ }
171
+ ```
172
+
173
+ To drive the generator functions, a loop like the following can be used:
106
174
 
107
175
  ```js
108
176
  const queue = [traverse.module(url, source, artifacts, visited)]
@@ -116,11 +184,13 @@ while (queue.length > 0) {
116
184
  const value = next.value
117
185
 
118
186
  if (value.module) {
119
- const source = /* Read `value.module` if it exists, otherwise `null` */;
187
+ // Read `value.module` if it exists, otherwise `null`
188
+ let source
120
189
 
121
190
  next = generator.next(source)
122
191
  } else if (value.prefix) {
123
- const modules = /* List the modules that have `value.prefix` as a prefix */;
192
+ // List the modules that have `value.prefix` as a prefix
193
+ let modules
124
194
 
125
195
  next = generator.next(modules)
126
196
  } else {
package/index.js CHANGED
@@ -1,10 +1,15 @@
1
- const { lookupPackageScope } = require('bare-module-resolve')
1
+ const { lookupPackageScope, conditionMatches } = require('bare-module-resolve')
2
2
  const { lookupPrebuildsScope } = require('bare-addon-resolve')
3
3
  const lex = require('bare-module-lexer')
4
4
  const resolve = require('./lib/resolve')
5
5
  const errors = require('./lib/errors')
6
6
 
7
- module.exports = exports = function traverse (entry, opts, readModule, listPrefix) {
7
+ module.exports = exports = function traverse(
8
+ entry,
9
+ opts,
10
+ readModule,
11
+ listPrefix
12
+ ) {
8
13
  if (typeof opts === 'function') {
9
14
  listPrefix = readModule
10
15
  readModule = opts
@@ -16,7 +21,7 @@ module.exports = exports = function traverse (entry, opts, readModule, listPrefi
16
21
  }
17
22
 
18
23
  return {
19
- * [Symbol.iterator] () {
24
+ *[Symbol.iterator]() {
20
25
  const artifacts = { addons: [], assets: [] }
21
26
 
22
27
  const queue = [exports.module(entry, null, artifacts, new Set(), opts)]
@@ -51,7 +56,7 @@ module.exports = exports = function traverse (entry, opts, readModule, listPrefi
51
56
  return artifacts
52
57
  },
53
58
 
54
- async * [Symbol.asyncIterator] () {
59
+ async *[Symbol.asyncIterator]() {
55
60
  const artifacts = { addons: [], assets: [] }
56
61
 
57
62
  const queue = [exports.module(entry, null, artifacts, new Set(), opts)]
@@ -88,51 +93,11 @@ module.exports = exports = function traverse (entry, opts, readModule, listPrefi
88
93
  }
89
94
  }
90
95
 
91
- function * defaultListPrefix () {}
92
-
93
- function addURL (array, url) {
94
- let lo = 0
95
- let hi = array.length - 1
96
-
97
- while (lo <= hi) {
98
- const mid = lo + ((hi - lo) >> 1)
99
- const found = array[mid]
100
-
101
- if (found.href === url.href) return
102
-
103
- if (found.href < url.href) {
104
- lo = mid + 1
105
- } else {
106
- hi = mid - 1
107
- }
108
- }
109
-
110
- array.splice(lo, 0, url)
111
- }
112
-
113
- function removeURL (array, url) {
114
- let lo = 0
115
- let hi = array.length - 1
116
-
117
- while (lo <= hi) {
118
- const mid = lo + ((hi - lo) >> 1)
119
- const found = array[mid]
120
-
121
- if (found.href === url.href) break
122
-
123
- if (found.href < url.href) {
124
- lo = mid + 1
125
- } else {
126
- hi = mid - 1
127
- }
128
- }
129
-
130
- if (array[lo].href === url.href) array.splice(lo, 1)
131
- }
96
+ function* defaultListPrefix() {}
132
97
 
133
98
  exports.resolve = resolve
134
99
 
135
- exports.module = function * (url, source, artifacts, visited, opts = {}) {
100
+ exports.module = function* (url, source, artifacts, visited, opts = {}) {
136
101
  const { resolutions = null } = opts
137
102
 
138
103
  if (visited.has(url.href)) return false
@@ -148,7 +113,16 @@ exports.module = function * (url, source, artifacts, visited, opts = {}) {
148
113
  visited.add(url.href)
149
114
 
150
115
  if (resolutions) {
151
- if (yield * exports.preresolved(url, source, resolutions, artifacts, visited, opts)) {
116
+ if (
117
+ yield* exports.preresolved(
118
+ url,
119
+ source,
120
+ resolutions,
121
+ artifacts,
122
+ visited,
123
+ opts
124
+ )
125
+ ) {
152
126
  return true
153
127
  }
154
128
  }
@@ -161,20 +135,22 @@ exports.module = function * (url, source, artifacts, visited, opts = {}) {
161
135
  if (source !== null) {
162
136
  imports['#package'] = packageURL.href
163
137
 
164
- yield { children: exports.package(packageURL, source, artifacts, visited, opts) }
138
+ yield {
139
+ children: exports.package(packageURL, source, artifacts, visited, opts)
140
+ }
165
141
 
166
142
  break
167
143
  }
168
144
  }
169
145
 
170
- yield * exports.imports(url, source, imports, artifacts, visited, opts)
146
+ yield* exports.imports(url, source, imports, artifacts, visited, opts)
171
147
 
172
148
  yield { dependency: { url, source, imports: compressImportsMap(imports) } }
173
149
 
174
150
  return true
175
151
  }
176
152
 
177
- exports.package = function * (url, source, artifacts, visited, opts = {}) {
153
+ exports.package = function* (url, source, artifacts, visited, opts = {}) {
178
154
  if (visited.has(url.href)) return false
179
155
 
180
156
  visited.add(url.href)
@@ -189,7 +165,9 @@ exports.package = function * (url, source, artifacts, visited, opts = {}) {
189
165
  }
190
166
 
191
167
  if (info.assets) {
192
- yield { children: exports.assets(info.assets, url, artifacts, visited, opts) }
168
+ yield {
169
+ children: exports.assets(info.assets, url, artifacts, visited, opts)
170
+ }
193
171
  }
194
172
 
195
173
  return true
@@ -198,7 +176,14 @@ exports.package = function * (url, source, artifacts, visited, opts = {}) {
198
176
  return false
199
177
  }
200
178
 
201
- exports.preresolved = function * (url, source, resolutions, artifacts, visited, opts = {}) {
179
+ exports.preresolved = function* (
180
+ url,
181
+ source,
182
+ resolutions,
183
+ artifacts,
184
+ visited,
185
+ opts = {}
186
+ ) {
202
187
  const imports = resolutions[url.href]
203
188
 
204
189
  if (typeof imports !== 'object' || imports === null) return false
@@ -213,9 +198,13 @@ exports.preresolved = function * (url, source, resolutions, artifacts, visited,
213
198
  const url = new URL(entry)
214
199
 
215
200
  if (specifier === '#package') {
216
- yield { children: exports.package(url, null, artifacts, visited, opts) }
201
+ yield {
202
+ children: exports.package(url, null, artifacts, visited, opts)
203
+ }
217
204
  } else {
218
- yield { children: exports.module(url, null, artifacts, visited, opts) }
205
+ yield {
206
+ children: exports.module(url, null, artifacts, visited, opts)
207
+ }
219
208
  }
220
209
  } else {
221
210
  stack.unshift(...Object.values(entry))
@@ -228,103 +217,145 @@ exports.preresolved = function * (url, source, resolutions, artifacts, visited,
228
217
  return true
229
218
  }
230
219
 
231
- exports.imports = function * (parentURL, source, imports, artifacts, visited, opts = {}) {
232
- const { resolve = exports.resolve.default, builtinProtocol = 'builtin:', linkedProtocol = 'linked:' } = opts
220
+ exports.imports = function* (
221
+ parentURL,
222
+ source,
223
+ imports,
224
+ artifacts,
225
+ visited,
226
+ opts = {}
227
+ ) {
228
+ const {
229
+ resolve = exports.resolve.default,
230
+ builtinProtocol = 'builtin:',
231
+ linkedProtocol = 'linked:',
232
+ matchedConditions = []
233
+ } = opts
233
234
 
234
235
  let yielded = false
235
236
 
236
237
  for (const entry of lex(source).imports) {
237
- const resolver = resolve(entry, parentURL, opts)
238
-
239
- let next = resolver.next()
240
- let resolved = false
241
238
  let specifier = entry.specifier
242
- let key = 'default'
239
+ let condition = 'default'
243
240
 
244
241
  if (entry.type & lex.constants.ADDON) {
245
242
  specifier = specifier || '.'
246
- key = 'addon'
243
+ condition = 'addon'
247
244
  } else if (entry.type & lex.constants.ASSET) {
248
- key = 'asset'
245
+ condition = 'asset'
249
246
  }
250
247
 
248
+ matchedConditions.push(condition)
249
+
250
+ const resolver = resolve(entry, parentURL, { ...opts, matchedConditions })
251
+
252
+ let next = resolver.next()
253
+ let resolutions = 0
254
+
251
255
  while (next.done !== true) {
252
256
  const value = next.value
253
257
 
254
258
  if (value.package) {
255
259
  next = resolver.next(JSON.parse(yield { module: value.package }))
260
+ } else if (hasResolution(imports, specifier, matchedConditions)) {
261
+ next = resolver.next(false)
256
262
  } else {
257
263
  const url = value.resolution
258
264
 
259
- if (url.protocol === builtinProtocol || url.protocol === linkedProtocol) {
260
- if (key === 'addon') addURL(artifacts.addons, url)
261
- else if (key === 'asset') addURL(artifacts.assets, url)
265
+ let resolved = false
262
266
 
263
- imports[specifier] = { [key]: url.href, ...imports[specifier] }
267
+ if (
268
+ url.protocol === builtinProtocol ||
269
+ url.protocol === linkedProtocol
270
+ ) {
271
+ if (addResolution(imports, specifier, matchedConditions, url)) {
272
+ resolved = yielded = true
273
+ }
274
+ } else {
275
+ const source = yield { module: url }
264
276
 
265
- resolved = yielded = true
277
+ if (source !== null) {
278
+ if (addResolution(imports, specifier, matchedConditions, url)) {
279
+ yield {
280
+ children: exports.module(url, source, artifacts, visited, opts)
281
+ }
266
282
 
267
- break
283
+ resolved = yielded = true
284
+ }
285
+ }
268
286
  }
269
287
 
270
- const source = yield { module: url }
271
-
272
- if (source !== null) {
273
- if (key === 'addon') addURL(artifacts.addons, url)
274
- else if (key === 'asset') addURL(artifacts.assets, url)
288
+ if (resolved) {
289
+ if (condition === 'addon') addURL(artifacts.addons, url)
290
+ else if (condition === 'asset') addURL(artifacts.assets, url)
275
291
 
276
- imports[specifier] = { [key]: url.href, ...imports[specifier] }
277
-
278
- yield { children: exports.module(url, source, artifacts, visited, opts) }
279
-
280
- resolved = yielded = true
281
-
282
- break
292
+ resolutions++
283
293
  }
284
294
 
285
- next = resolver.next()
295
+ next = resolver.next(resolved)
286
296
  }
287
297
  }
288
298
 
289
- if (!resolved) {
290
- switch (key) {
291
- case 'addon':
292
- throw errors.ADDON_NOT_FOUND(`Cannot find addon '${specifier}' imported from '${parentURL.href}'`)
293
- case 'asset':
294
- throw errors.ASSET_NOT_FOUND(`Cannot find asset '${specifier}' imported from '${parentURL.href}'`)
295
- default:
296
- throw errors.MODULE_NOT_FOUND(`Cannot find module '${specifier}' imported from '${parentURL.href}'`)
297
- }
299
+ matchedConditions.pop()
300
+
301
+ if (resolutions === 0) {
302
+ throw errors.ADDON_NOT_FOUND(
303
+ `Cannot find ${condition === 'default' ? 'module' : condition} '${specifier}' imported from '${parentURL.href}'`
304
+ )
298
305
  }
299
306
  }
300
307
 
301
308
  return yielded
302
309
  }
303
310
 
304
- exports.prebuilds = function * (packageURL, artifacts, visited, opts = {}) {
305
- const [prefix = null] = lookupPrebuildsScope(packageURL, opts)
311
+ exports.prebuilds = function* (packageURL, artifacts, visited, opts = {}) {
312
+ const {
313
+ host = null, // Shorthand for single host resolution
314
+ hosts = host !== null ? [host] : [],
315
+ matchedConditions = []
316
+ } = opts
306
317
 
307
- if (prefix === null) return false
318
+ const [prebuildsURL = null] = lookupPrebuildsScope(packageURL, opts)
319
+
320
+ if (prebuildsURL === null) return false
308
321
 
309
322
  let yielded = false
310
323
 
311
- for (const url of yield { prefix }) {
312
- const source = yield { module: url }
324
+ for (const host of hosts) {
325
+ const prefix = new URL(host + '/', prebuildsURL)
313
326
 
314
- if (source !== null) {
315
- addURL(artifacts.addons, url)
327
+ const conditions = host.split('-')
316
328
 
317
- yield { children: exports.module(url, source, artifacts, visited, opts) }
329
+ matchedConditions.push(...conditions)
318
330
 
319
- yielded = true
331
+ for (const url of yield { prefix }) {
332
+ const source = yield { module: url }
333
+
334
+ if (source !== null) {
335
+ addURL(artifacts.addons, url)
336
+
337
+ yield {
338
+ children: exports.module(url, source, artifacts, visited, opts)
339
+ }
340
+
341
+ yielded = true
342
+ }
320
343
  }
344
+
345
+ for (const _ of conditions) matchedConditions.pop()
321
346
  }
322
347
 
323
348
  return yielded
324
349
  }
325
350
 
326
- exports.assets = function * (patterns, parentURL, artifacts, visited, opts = {}) {
327
- const matches = yield * exports.patternMatches(patterns, parentURL, [], opts)
351
+ exports.assets = function* (
352
+ patterns,
353
+ parentURL,
354
+ artifacts,
355
+ visited,
356
+ opts = {}
357
+ ) {
358
+ const matches = yield* exports.patternMatches(patterns, parentURL, [], opts)
328
359
 
329
360
  let yielded = false
330
361
 
@@ -343,8 +374,13 @@ exports.assets = function * (patterns, parentURL, artifacts, visited, opts = {})
343
374
  return yielded
344
375
  }
345
376
 
346
- exports.patternMatches = function * (pattern, parentURL, matches, opts = {}) {
347
- const { conditions = [] } = opts
377
+ exports.patternMatches = function* patternMatches(
378
+ pattern,
379
+ parentURL,
380
+ matches,
381
+ opts = {}
382
+ ) {
383
+ const { conditions = [], matchedConditions = [] } = opts
348
384
 
349
385
  if (typeof pattern === 'string') {
350
386
  let patternNegate = false
@@ -380,24 +416,127 @@ exports.patternMatches = function * (pattern, parentURL, matches, opts = {}) {
380
416
  }
381
417
  } else if (Array.isArray(pattern)) {
382
418
  for (const patternValue of pattern) {
383
- yield * exports.patternMatches(patternValue, parentURL, matches, opts)
419
+ yield* patternMatches(patternValue, parentURL, matches, opts)
384
420
  }
385
421
  } else if (typeof pattern === 'object' && pattern !== null) {
386
- const keys = Object.keys(pattern)
387
-
388
- for (const p of keys) {
389
- if (p === 'default' || conditions.includes(p)) {
390
- const patternValue = pattern[p]
391
-
392
- return yield * exports.patternMatches(patternValue, parentURL, matches, opts)
422
+ let yielded = false
423
+
424
+ for (const [condition, patternValue, subset] of conditionMatches(
425
+ pattern,
426
+ conditions,
427
+ opts
428
+ )) {
429
+ matchedConditions.push(condition)
430
+
431
+ if (
432
+ yield* patternMatches(patternValue, parentURL, matches, {
433
+ ...opts,
434
+ conditions: subset
435
+ })
436
+ ) {
437
+ yielded = true
393
438
  }
439
+
440
+ matchedConditions.pop()
394
441
  }
442
+
443
+ if (yielded) return true
395
444
  }
396
445
 
397
446
  return matches
398
447
  }
399
448
 
400
- function compressImportsMap (imports) {
449
+ function addURL(array, url) {
450
+ let lo = 0
451
+ let hi = array.length - 1
452
+
453
+ while (lo <= hi) {
454
+ const mid = lo + ((hi - lo) >> 1)
455
+ const found = array[mid]
456
+
457
+ if (found.href === url.href) return
458
+
459
+ if (found.href < url.href) {
460
+ lo = mid + 1
461
+ } else {
462
+ hi = mid - 1
463
+ }
464
+ }
465
+
466
+ array.splice(lo, 0, url)
467
+ }
468
+
469
+ function removeURL(array, url) {
470
+ let lo = 0
471
+ let hi = array.length - 1
472
+
473
+ while (lo <= hi) {
474
+ const mid = lo + ((hi - lo) >> 1)
475
+ const found = array[mid]
476
+
477
+ if (found.href === url.href) break
478
+
479
+ if (found.href < url.href) {
480
+ lo = mid + 1
481
+ } else {
482
+ hi = mid - 1
483
+ }
484
+ }
485
+
486
+ if (array[lo].href === url.href) array.splice(lo, 1)
487
+ }
488
+
489
+ function hasResolution(imports, specifier, conditions) {
490
+ if (specifier in imports === false) return false
491
+
492
+ let current = imports[specifier]
493
+
494
+ for (const key of conditions) {
495
+ if (key in current === false || typeof current[key] !== 'object') {
496
+ return false
497
+ }
498
+
499
+ current = current[key]
500
+ }
501
+
502
+ return true
503
+ }
504
+
505
+ function addResolution(imports, specifier, conditions, url) {
506
+ imports[specifier] = imports[specifier] || {}
507
+
508
+ let current = imports[specifier]
509
+
510
+ for (let i = 0, n = conditions.length - 1; i < n; i++) {
511
+ const key = conditions[i]
512
+
513
+ if (key in current === false) {
514
+ current[key] = {}
515
+ } else if (typeof current[key] !== 'object') {
516
+ current[key] = { default: current[key] }
517
+ }
518
+
519
+ current = current[key]
520
+ }
521
+
522
+ const last = conditions[conditions.length - 1]
523
+
524
+ if (last in current) return false
525
+
526
+ current[last] = url.href
527
+
528
+ if ('default' in current) {
529
+ const value = current.default
530
+
531
+ delete current.default
532
+
533
+ current.default = value
534
+ }
535
+
536
+ return true
537
+ }
538
+
539
+ function compressImportsMap(imports) {
401
540
  const entries = []
402
541
 
403
542
  for (const entry of Object.entries(imports)) {
@@ -409,7 +548,7 @@ function compressImportsMap (imports) {
409
548
  return Object.fromEntries(entries)
410
549
  }
411
550
 
412
- function compressImportsMapEntry (resolved) {
551
+ function compressImportsMapEntry(resolved) {
413
552
  if (typeof resolved === 'string') return resolved
414
553
 
415
554
  let entries = []
@@ -423,13 +562,11 @@ function compressImportsMapEntry (resolved) {
423
562
  if (entry[0] === 'default') primary = entry[1]
424
563
  }
425
564
 
426
- entries = entries.filter(([condition, resolved]) => condition === 'default' || resolved !== primary)
565
+ entries = entries.filter(
566
+ ([condition, resolved]) => condition === 'default' || resolved !== primary
567
+ )
427
568
 
428
- if (entries.length === 1) {
429
- const [condition, resolved] = entries[0]
430
-
431
- if (condition === 'default') return resolved
432
- }
569
+ if (entries.length === 1) return entries[0][1]
433
570
 
434
571
  return Object.fromEntries(entries)
435
572
  }
package/lib/errors.js CHANGED
@@ -1,5 +1,5 @@
1
1
  module.exports = class ModuleTraverseError extends Error {
2
- constructor (msg, code, fn = ModuleTraverseError) {
2
+ constructor(msg, code, fn = ModuleTraverseError) {
3
3
  super(`${code}: ${msg}`)
4
4
  this.code = code
5
5
 
@@ -8,19 +8,31 @@ module.exports = class ModuleTraverseError extends Error {
8
8
  }
9
9
  }
10
10
 
11
- get name () {
11
+ get name() {
12
12
  return 'ModuleTraverseError'
13
13
  }
14
14
 
15
- static MODULE_NOT_FOUND (msg) {
16
- return new ModuleTraverseError(msg, 'MODULE_NOT_FOUND', ModuleTraverseError.MODULE_NOT_FOUND)
15
+ static MODULE_NOT_FOUND(msg) {
16
+ return new ModuleTraverseError(
17
+ msg,
18
+ 'MODULE_NOT_FOUND',
19
+ ModuleTraverseError.MODULE_NOT_FOUND
20
+ )
17
21
  }
18
22
 
19
- static ADDON_NOT_FOUND (msg) {
20
- return new ModuleTraverseError(msg, 'ADDON_NOT_FOUND', ModuleTraverseError.ADDON_NOT_FOUND)
23
+ static ADDON_NOT_FOUND(msg) {
24
+ return new ModuleTraverseError(
25
+ msg,
26
+ 'ADDON_NOT_FOUND',
27
+ ModuleTraverseError.ADDON_NOT_FOUND
28
+ )
21
29
  }
22
30
 
23
- static ASSET_NOT_FOUND (msg) {
24
- return new ModuleTraverseError(msg, 'ASSET_NOT_FOUND', ModuleTraverseError.ASSET_NOT_FOUND)
31
+ static ASSET_NOT_FOUND(msg) {
32
+ return new ModuleTraverseError(
33
+ msg,
34
+ 'ASSET_NOT_FOUND',
35
+ ModuleTraverseError.ASSET_NOT_FOUND
36
+ )
25
37
  }
26
38
  }
@@ -9,32 +9,41 @@ module.exports = function (entry, parentURL, opts = {}) {
9
9
  platform = runtime.platform,
10
10
  arch = runtime.arch,
11
11
  simulator = false,
12
- host = `${platform}-${arch}${simulator ? '-simulator' : ''}`
12
+ host = `${platform}-${arch}${simulator ? '-simulator' : ''}`,
13
+ target = [host]
13
14
  } = opts
14
15
 
15
16
  let extensions
16
- let conditions = ['bare', 'node', platform, arch]
17
-
18
- if (simulator) conditions = [...conditions, 'simulator']
17
+ let conditions = target.map((host) => ['bare', 'node', ...host.split('-')])
19
18
 
20
19
  if (entry.type & lex.constants.ADDON) {
21
20
  extensions = linked ? [] : ['.bare', '.node']
22
- conditions = ['addon', ...conditions]
23
-
24
- return resolve.addon(entry.specifier || '.', parentURL, { extensions, conditions, host, linked, ...opts })
21
+ conditions = conditions.map((conditions) => ['addon', ...conditions])
22
+
23
+ return resolve.addon(entry.specifier || '.', parentURL, {
24
+ extensions,
25
+ conditions,
26
+ hosts: target,
27
+ linked,
28
+ ...opts
29
+ })
25
30
  }
26
31
 
27
32
  if (entry.type & lex.constants.ASSET) {
28
- conditions = ['asset', ...conditions]
33
+ conditions = conditions.map((conditions) => ['asset', ...conditions])
29
34
  } else {
30
35
  extensions = ['.js', '.cjs', '.mjs', '.json', '.bare', '.node']
31
36
 
32
37
  if (entry.type & lex.constants.REQUIRE) {
33
- conditions = ['require', ...conditions]
38
+ conditions = conditions.map((conditions) => ['require', ...conditions])
34
39
  } else if (entry.type & lex.constants.IMPORT) {
35
- conditions = ['import', ...conditions]
40
+ conditions = conditions.map((conditions) => ['import', ...conditions])
36
41
  }
37
42
  }
38
43
 
39
- return resolve.module(entry.specifier, parentURL, { extensions, conditions, ...opts })
44
+ return resolve.module(entry.specifier, parentURL, {
45
+ extensions,
46
+ conditions,
47
+ ...opts
48
+ })
40
49
  }
@@ -8,27 +8,39 @@ module.exports = function (entry, parentURL, opts = {}) {
8
8
  platform = runtime.platform,
9
9
  arch = runtime.arch,
10
10
  simulator = false,
11
- host = `${platform}-${arch}${simulator ? '-simulator' : ''}`
11
+ host = `${platform}-${arch}${simulator ? '-simulator' : ''}`,
12
+ target = [host]
12
13
  } = opts
13
14
 
14
15
  let extensions
15
- let conditions = ['node', platform, arch]
16
-
17
- if (simulator) conditions = [...conditions, 'simulator']
16
+ let conditions
18
17
 
19
18
  if (entry.type & lex.constants.ADDON) {
20
19
  extensions = ['.node']
21
- conditions = ['addon', ...conditions]
22
-
23
- return resolve.addon(entry.specifier || '.', parentURL, { extensions, conditions, host, ...opts })
20
+ conditions = target.map((host) => ['node', 'addon', ...host.split('-')])
21
+
22
+ return resolve.addon(entry.specifier || '.', parentURL, {
23
+ extensions,
24
+ conditions,
25
+ host,
26
+ ...opts
27
+ })
24
28
  }
25
29
 
26
- if (entry.type & lex.constants.REQUIRE) {
30
+ if (entry.type & lex.constants.ASSET) {
31
+ conditions = ['node', 'asset']
32
+ } else if (entry.type & lex.constants.REQUIRE) {
27
33
  extensions = ['.js', '.json', '.node']
28
34
  conditions = ['node', 'require']
29
35
  } else if (entry.type & lex.constants.IMPORT) {
30
36
  conditions = ['node', 'import']
37
+ } else {
38
+ conditions = ['node']
31
39
  }
32
40
 
33
- return resolve.module(entry.specifier, parentURL, { extensions, conditions, ...opts })
41
+ return resolve.module(entry.specifier, parentURL, {
42
+ extensions,
43
+ conditions,
44
+ ...opts
45
+ })
34
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-module-traverse",
3
- "version": "1.2.6",
3
+ "version": "1.3.0",
4
4
  "description": "Low-level module graph traversal for Bare",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -24,7 +24,7 @@
24
24
  "test": "npm run lint && npm run test:bare && npm run test:node",
25
25
  "test:bare": "bare test.js",
26
26
  "test:node": "node test.js",
27
- "lint": "standard"
27
+ "lint": "prettier . --check"
28
28
  },
29
29
  "repository": {
30
30
  "type": "git",
@@ -43,6 +43,7 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "brittle": "^3.2.1",
46
- "standard": "^17.0.0"
46
+ "prettier": "^3.4.2",
47
+ "prettier-config-standard": "^7.0.0"
47
48
  }
48
49
  }