bare-module-traverse 1.0.1 → 1.2.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
@@ -17,8 +17,8 @@ function readModule (url) {
17
17
  // Read `url` if it exists, otherwise `null`
18
18
  }
19
19
 
20
- function listPrefix (url) {
21
- // Return a list of URLs that have `url` as a prefix. The list may be empty.
20
+ function * listPrefix (url) {
21
+ // Yield URLs that have `url` as a prefix. The list may be empty.
22
22
  }
23
23
 
24
24
  for (const dependency of traverse(new URL('file:///directory/file.js'), readModule, listPrefix)) {
@@ -35,8 +35,8 @@ async function readModule (url) {
35
35
  // Read `url` if it exists, otherwise `null`
36
36
  }
37
37
 
38
- async function listPrefix (url) {
39
- // Return a list of URLs that have `url` as a prefix. The list may be empty.
38
+ async function * listPrefix (url) {
39
+ // Yield URLs that have `url` as a prefix. The list may be empty.
40
40
  }
41
41
 
42
42
  for await (const dependency of traverse(new URL('file:///directory/file.js'), readModule, listPrefix)) {
@@ -48,7 +48,17 @@ for await (const dependency of traverse(new URL('file:///directory/file.js'), re
48
48
 
49
49
  #### `const dependencies = traverse(url[, options], readModule[, listPrefix])`
50
50
 
51
- Traverse the module graph rooted at `url`, which must be a WHATWG `URL` instance. `readModule` is called with a `URL` instance for every module to be read and must either return the module source, if it exists, or `null`. `listPrefix` is called with a `URL` instance of every prefix to be listed and must return a list of `URL` instances that have the specified `URL` as a prefix. If not provided, prefixes won't be traversed. If one or both of `readModule` or `listPrefix` returns a promise, synchronous iteration is not supported.
51
+ Traverse the module graph rooted at `url`, which must be a WHATWG `URL` instance. `readModule` is called with a `URL` instance for every module to be read and must either return the module source, if it exists, or `null`. `listPrefix` is called with a `URL` instance of every prefix to be listed and must return a list of `URL` instances that have the specified `URL` as a prefix. If not provided, prefixes won't be traversed. If `readModule` returns a promise or `listPrefix` returns a promise generator, synchronous iteration is not supported.
52
+
53
+ Options include:
54
+
55
+ ```js
56
+ {
57
+ resolve: resolve.default
58
+ }
59
+ ```
60
+
61
+ Options supported by <https://github.com/holepunchto/bare-module-resolve> and <https://github.com/holepunchto/bare-addon-resolve> may also be specified.
52
62
 
53
63
  #### `for (const dependency of dependencies)`
54
64
 
@@ -66,7 +76,29 @@ Synchronously iterate the module graph. Each yielded dependency has the followin
66
76
 
67
77
  #### `for await (const dependency of dependencies)`
68
78
 
69
- Asynchronously iterate the module graph. If one or both of `readModule` or `listPrefix` returns promises, these will be awaited. The same comments as `for (const dependency of dependencies)` apply.
79
+ Asynchronously iterate the module graph. If `readModule` returns a promise or `listPrefix` returns a promise generator, these will be awaited. The same comments as `for (const dependency of dependencies)` apply.
80
+
81
+ ### Resolution
82
+
83
+ #### `resolve.module`
84
+
85
+ Convenience export from <https://github.com/holepunchto/bare-module-resolve>.
86
+
87
+ #### `resolve.addon`
88
+
89
+ Convenience export from <https://github.com/holepunchto/bare-addon-resolve>.
90
+
91
+ #### `resolve.default`
92
+
93
+ The default resolver, which simply forwards to <https://github.com/holepunchto/bare-module-resolve> and <https://github.com/holepunchto/bare-addon-resolve> with the literal options passed by the caller.
94
+
95
+ #### `resolve.bare`
96
+
97
+ The Bare resolver, which matches the options used by the Bare module system.
98
+
99
+ #### `resolve.node`
100
+
101
+ The Node.js resolver, which matches the options used by the Node.js module system.
70
102
 
71
103
  ### Algorithm
72
104
 
@@ -117,6 +149,8 @@ Options are the same as `traverse()` for all functions.
117
149
 
118
150
  #### `const generator = traverse.imports(parentURL, source, imports, artifacts, visited[, options])`
119
151
 
152
+ #### `const generator = traverse.prebuilds(packageURL, artifacts, visited[, options])`
153
+
120
154
  #### `const generator = traverse.assets(patterns, parentURL, artifacts, visited[, options])`
121
155
 
122
156
  ## License
package/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const { lookupPackageScope } = require('bare-module-resolve')
2
+ const { lookupPrebuildsScope } = require('bare-addon-resolve')
2
3
  const lex = require('bare-module-lexer')
3
4
  const resolve = require('./lib/resolve')
4
5
  const errors = require('./lib/errors')
@@ -16,7 +17,7 @@ module.exports = exports = function traverse (entry, opts, readModule, listPrefi
16
17
 
17
18
  return {
18
19
  * [Symbol.iterator] () {
19
- const artifacts = createArtifacts()
20
+ const artifacts = { addons: [], assets: [] }
20
21
 
21
22
  const queue = [exports.module(entry, null, artifacts, new Set(), opts)]
22
23
 
@@ -31,7 +32,13 @@ module.exports = exports = function traverse (entry, opts, readModule, listPrefi
31
32
  if (value.module) {
32
33
  next = generator.next(readModule(value.module))
33
34
  } else if (value.prefix) {
34
- next = generator.next(listPrefix(value.prefix))
35
+ const result = []
36
+
37
+ for (const url of listPrefix(value.prefix)) {
38
+ result.push(url)
39
+ }
40
+
41
+ next = generator.next(result)
35
42
  } else {
36
43
  if (value.children) queue.push(value.children)
37
44
  else yield value.dependency
@@ -45,7 +52,7 @@ module.exports = exports = function traverse (entry, opts, readModule, listPrefi
45
52
  },
46
53
 
47
54
  async * [Symbol.asyncIterator] () {
48
- const artifacts = createArtifacts()
55
+ const artifacts = { addons: [], assets: [] }
49
56
 
50
57
  const queue = [exports.module(entry, null, artifacts, new Set(), opts)]
51
58
 
@@ -60,7 +67,13 @@ module.exports = exports = function traverse (entry, opts, readModule, listPrefi
60
67
  if (value.module) {
61
68
  next = generator.next(await readModule(value.module))
62
69
  } else if (value.prefix) {
63
- next = generator.next(await listPrefix(value.prefix))
70
+ const result = []
71
+
72
+ for await (const url of listPrefix(value.prefix)) {
73
+ result.push(url)
74
+ }
75
+
76
+ next = generator.next(result)
64
77
  } else {
65
78
  if (value.children) queue.push(value.children)
66
79
  else yield value.dependency
@@ -79,19 +92,27 @@ function defaultListPrefix () {
79
92
  return []
80
93
  }
81
94
 
82
- function defaultResolve (entry, parentURL, opts) {
83
- if (entry.type & lex.constants.ADDON) {
84
- return resolve.addon(entry.specifier, parentURL, opts)
85
- } else {
86
- return resolve.module(entry.specifier, parentURL, opts)
95
+ function addURL (array, url) {
96
+ let lo = 0
97
+ let hi = array.length - 1
98
+
99
+ while (lo <= hi) {
100
+ const mid = lo + ((hi - lo) >> 1)
101
+ const found = array[mid]
102
+
103
+ if (found.href === url.href) return
104
+
105
+ if (found.href < url.href) {
106
+ lo = mid + 1
107
+ } else {
108
+ hi = mid - 1
109
+ }
87
110
  }
88
- }
89
111
 
90
- function createArtifacts () {
91
- return { addons: [], assets: [] }
112
+ array.splice(lo, 0, url)
92
113
  }
93
114
 
94
- function addURL (array, url) {
115
+ function removeURL (array, url) {
95
116
  let lo = 0
96
117
  let hi = array.length - 1
97
118
 
@@ -99,7 +120,7 @@ function addURL (array, url) {
99
120
  const mid = lo + ((hi - lo) >> 1)
100
121
  const found = array[mid]
101
122
 
102
- if (found.href === url.href) return
123
+ if (found.href === url.href) break
103
124
 
104
125
  if (found.href < url.href) {
105
126
  lo = mid + 1
@@ -108,7 +129,7 @@ function addURL (array, url) {
108
129
  }
109
130
  }
110
131
 
111
- array.splice(lo, 0, url)
132
+ if (array[lo].href === url.href) array.splice(lo, 1)
112
133
  }
113
134
 
114
135
  exports.resolve = resolve
@@ -163,6 +184,10 @@ exports.package = function * (url, source, artifacts, visited, opts = {}) {
163
184
  if (info) {
164
185
  yield { dependency: { url, source, imports: {} } }
165
186
 
187
+ if (info.addon) {
188
+ yield { children: exports.prebuilds(url, artifacts, visited, opts) }
189
+ }
190
+
166
191
  if (info.assets) {
167
192
  yield { children: exports.assets(info.assets, url, artifacts, visited, opts) }
168
193
  }
@@ -204,7 +229,7 @@ exports.preresolved = function * (url, source, resolutions, artifacts, visited,
204
229
  }
205
230
 
206
231
  exports.imports = function * (parentURL, source, imports, artifacts, visited, opts = {}) {
207
- const { resolve = defaultResolve } = opts
232
+ const { resolve = exports.resolve.default } = opts
208
233
 
209
234
  let yielded = false
210
235
 
@@ -258,13 +283,34 @@ exports.imports = function * (parentURL, source, imports, artifacts, visited, op
258
283
  return yielded
259
284
  }
260
285
 
286
+ exports.prebuilds = function * (packageURL, artifacts, visited, opts = {}) {
287
+ const [prefix = null] = lookupPrebuildsScope(packageURL, opts)
288
+
289
+ if (prefix === null) return false
290
+
291
+ let yielded = false
292
+
293
+ for (const url of yield { prefix }) {
294
+ const source = yield { module: url }
295
+
296
+ if (source !== null) {
297
+ addURL(artifacts.addons, url)
298
+
299
+ yield { children: exports.module(url, source, artifacts, visited, opts) }
300
+
301
+ yielded = true
302
+ }
303
+ }
304
+
305
+ return yielded
306
+ }
307
+
261
308
  exports.assets = function * (patterns, parentURL, artifacts, visited, opts = {}) {
262
- const matches = yield * exports.matches(patterns, parentURL, opts)
309
+ const matches = yield * exports.patternMatches(patterns, parentURL, [], opts)
263
310
 
264
311
  let yielded = false
265
312
 
266
- for (const href of matches) {
267
- const url = new URL(href)
313
+ for (const url of matches) {
268
314
  const source = yield { module: url }
269
315
 
270
316
  if (source !== null) {
@@ -279,10 +325,10 @@ exports.assets = function * (patterns, parentURL, artifacts, visited, opts = {})
279
325
  return yielded
280
326
  }
281
327
 
282
- exports.matches = function * (patterns, parentURL) {
283
- const matches = new Set()
328
+ exports.patternMatches = function * (pattern, parentURL, matches, opts = {}) {
329
+ const { conditions = [] } = opts
284
330
 
285
- for (let pattern of patterns) {
331
+ if (typeof pattern === 'string') {
286
332
  let patternNegate = false
287
333
  let patternBase
288
334
  let patternTrailer
@@ -306,12 +352,26 @@ exports.matches = function * (patterns, parentURL) {
306
352
 
307
353
  for (const url of yield { prefix }) {
308
354
  if (patternIndex === -1) {
309
- if (patternNegate) matches.delete(url.href)
310
- else matches.add(url.href)
355
+ if (patternNegate) removeURL(matches, url)
356
+ else addURL(matches, url)
311
357
  } else if (patternTrailer === '' || url.href.endsWith(patternTrailer)) {
312
- matches.add(url.href)
358
+ addURL(matches, url)
313
359
  } else if (patternNegate) {
314
- matches.delete(url.href)
360
+ removeURL(matches, url)
361
+ }
362
+ }
363
+ } else if (Array.isArray(pattern)) {
364
+ for (const patternValue of pattern) {
365
+ yield * exports.patternMatches(patternValue, parentURL, matches, opts)
366
+ }
367
+ } else if (typeof pattern === 'object' && pattern !== null) {
368
+ const keys = Object.keys(pattern)
369
+
370
+ for (const p of keys) {
371
+ if (p === 'default' || conditions.includes(p)) {
372
+ const patternValue = pattern[p]
373
+
374
+ return yield * exports.patternMatches(patternValue, parentURL, matches, opts)
315
375
  }
316
376
  }
317
377
  }
package/lib/resolve.js CHANGED
@@ -1,2 +1,68 @@
1
+ const lex = require('bare-module-lexer')
2
+
1
3
  exports.module = require('bare-module-resolve').module
2
4
  exports.addon = require('bare-addon-resolve').addon
5
+
6
+ exports.default = function resolve (entry, parentURL, opts) {
7
+ if (entry.type & lex.constants.ADDON) {
8
+ return exports.addon(entry.specifier, parentURL, opts)
9
+ }
10
+
11
+ return exports.module(entry.specifier, parentURL, opts)
12
+ }
13
+
14
+ exports.bare = function resolve (entry, parentURL, opts = {}) {
15
+ const runtime = require('#runtime')
16
+
17
+ const {
18
+ platform = runtime.platform,
19
+ arch = runtime.arch,
20
+ simulator = false
21
+ } = opts
22
+
23
+ let extensions
24
+ let conditions = ['bare', 'node', platform, arch]
25
+
26
+ if (simulator) conditions = [...conditions, 'simulator']
27
+
28
+ if (entry.type & lex.constants.ADDON) {
29
+ extensions = ['.bare', '.node']
30
+ conditions = ['addon', ...conditions]
31
+
32
+ return exports.addon(entry.specifier, parentURL, { extensions, conditions, ...opts })
33
+ }
34
+
35
+ if (entry.type & lex.constants.ASSET) {
36
+ conditions = ['asset', ...conditions]
37
+ } else {
38
+ extensions = ['.js', '.cjs', '.mjs', '.json', '.bare', '.node']
39
+
40
+ if (entry.type & lex.constants.REQUIRE) {
41
+ conditions = ['require', ...conditions]
42
+ } else if (entry.type & lex.constants.IMPORT) {
43
+ conditions = ['import', ...conditions]
44
+ }
45
+ }
46
+
47
+ return exports.module(entry.specifier, parentURL, { extensions, conditions, ...opts })
48
+ }
49
+
50
+ exports.node = function resolve (entry, parentURL, opts) {
51
+ let extensions
52
+ let conditions
53
+
54
+ if (entry.type & lex.constants.ADDON) {
55
+ extensions = ['.node']
56
+
57
+ return exports.addon(entry.specifier, parentURL, { extensions, conditions, ...opts })
58
+ }
59
+
60
+ if (entry.type & lex.constants.REQUIRE) {
61
+ extensions = ['.js', '.json', '.node']
62
+ conditions = ['node', 'require']
63
+ } else if (entry.type & lex.constants.IMPORT) {
64
+ conditions = ['node', 'import']
65
+ }
66
+
67
+ return exports.module(entry.specifier, parentURL, { extensions, conditions, ...opts })
68
+ }
@@ -0,0 +1,3 @@
1
+ /* global Bare */
2
+ exports.platform = Bare.platform
3
+ exports.arch = Bare.arch
@@ -0,0 +1,2 @@
1
+ exports.platform = process.platform
2
+ exports.arch = process.arch
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-module-traverse",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "description": "Low-level module graph traversal for Bare",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -11,6 +11,12 @@
11
11
  "index.js",
12
12
  "lib"
13
13
  ],
14
+ "imports": {
15
+ "#runtime": {
16
+ "bare": "./lib/runtime/bare.js",
17
+ "node": "./lib/runtime/node.js"
18
+ }
19
+ },
14
20
  "scripts": {
15
21
  "test": "standard && bare test.js"
16
22
  },