@mrclrchtr/supi-lsp 11.0.1 → 11.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.
Files changed (85) hide show
  1. package/README.md +43 -6
  2. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  3. package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  4. package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +41 -1
  5. package/node_modules/ignore/README.md +36 -10
  6. package/node_modules/ignore/index.d.ts +3 -2
  7. package/node_modules/ignore/index.js +57 -53
  8. package/node_modules/ignore/legacy.js +50 -46
  9. package/node_modules/ignore/package.json +1 -1
  10. package/node_modules/semver/LICENSE +15 -0
  11. package/node_modules/semver/README.md +680 -0
  12. package/node_modules/semver/bin/semver.js +195 -0
  13. package/node_modules/semver/classes/comparator.js +143 -0
  14. package/node_modules/semver/classes/index.js +7 -0
  15. package/node_modules/semver/classes/range.js +577 -0
  16. package/node_modules/semver/classes/semver.js +350 -0
  17. package/node_modules/semver/functions/clean.js +8 -0
  18. package/node_modules/semver/functions/cmp.js +54 -0
  19. package/node_modules/semver/functions/coerce.js +62 -0
  20. package/node_modules/semver/functions/compare-build.js +9 -0
  21. package/node_modules/semver/functions/compare-loose.js +5 -0
  22. package/node_modules/semver/functions/compare.js +7 -0
  23. package/node_modules/semver/functions/diff.js +60 -0
  24. package/node_modules/semver/functions/eq.js +5 -0
  25. package/node_modules/semver/functions/gt.js +5 -0
  26. package/node_modules/semver/functions/gte.js +5 -0
  27. package/node_modules/semver/functions/inc.js +21 -0
  28. package/node_modules/semver/functions/lt.js +5 -0
  29. package/node_modules/semver/functions/lte.js +5 -0
  30. package/node_modules/semver/functions/major.js +5 -0
  31. package/node_modules/semver/functions/minor.js +5 -0
  32. package/node_modules/semver/functions/neq.js +5 -0
  33. package/node_modules/semver/functions/parse.js +18 -0
  34. package/node_modules/semver/functions/patch.js +5 -0
  35. package/node_modules/semver/functions/prerelease.js +8 -0
  36. package/node_modules/semver/functions/rcompare.js +5 -0
  37. package/node_modules/semver/functions/rsort.js +5 -0
  38. package/node_modules/semver/functions/satisfies.js +12 -0
  39. package/node_modules/semver/functions/sort.js +5 -0
  40. package/node_modules/semver/functions/truncate.js +48 -0
  41. package/node_modules/semver/functions/valid.js +8 -0
  42. package/node_modules/semver/index.js +93 -0
  43. package/node_modules/semver/internal/constants.js +37 -0
  44. package/node_modules/semver/internal/debug.js +11 -0
  45. package/node_modules/semver/internal/identifiers.js +29 -0
  46. package/node_modules/semver/internal/lrucache.js +42 -0
  47. package/node_modules/semver/internal/parse-options.js +17 -0
  48. package/node_modules/semver/internal/re.js +223 -0
  49. package/node_modules/semver/package.json +78 -0
  50. package/node_modules/semver/preload.js +4 -0
  51. package/node_modules/semver/range.bnf +17 -0
  52. package/node_modules/semver/ranges/gtr.js +6 -0
  53. package/node_modules/semver/ranges/intersects.js +9 -0
  54. package/node_modules/semver/ranges/ltr.js +6 -0
  55. package/node_modules/semver/ranges/max-satisfying.js +27 -0
  56. package/node_modules/semver/ranges/min-satisfying.js +26 -0
  57. package/node_modules/semver/ranges/min-version.js +63 -0
  58. package/node_modules/semver/ranges/outside.js +82 -0
  59. package/node_modules/semver/ranges/simplify.js +49 -0
  60. package/node_modules/semver/ranges/subset.js +249 -0
  61. package/node_modules/semver/ranges/to-comparators.js +10 -0
  62. package/node_modules/semver/ranges/valid.js +13 -0
  63. package/node_modules/vscode-jsonrpc/README.md +5 -0
  64. package/node_modules/vscode-jsonrpc/lib/browser/ril.js +8 -0
  65. package/node_modules/vscode-jsonrpc/lib/common/connection.js +7 -2
  66. package/node_modules/vscode-jsonrpc/lib/common/ral.d.ts +8 -0
  67. package/node_modules/vscode-jsonrpc/lib/node/main.d.ts +14 -0
  68. package/node_modules/vscode-jsonrpc/lib/node/main.js +6 -4
  69. package/node_modules/vscode-jsonrpc/lib/node/ril.js +5 -1
  70. package/node_modules/vscode-jsonrpc/package.json +4 -2
  71. package/node_modules/vscode-languageserver-protocol/package.json +4 -3
  72. package/node_modules/vscode-languageserver-types/lib/esm/main.js +2 -2
  73. package/node_modules/vscode-languageserver-types/lib/umd/main.js +2 -2
  74. package/node_modules/vscode-languageserver-types/package.json +2 -1
  75. package/package.json +8 -6
  76. package/src/client/client.ts +44 -5
  77. package/src/config/config.ts +53 -2
  78. package/src/config/operation-support.ts +19 -4
  79. package/src/config/server-config.ts +22 -0
  80. package/src/config/typescript-launch.ts +276 -0
  81. package/src/manager/manager-project-info.ts +22 -10
  82. package/src/manager/manager.ts +53 -20
  83. package/src/provider/refactor-planning.ts +4 -3
  84. package/src/session/runtime-controller.ts +2 -2
  85. package/src/session/scanner.ts +27 -15
@@ -0,0 +1,27 @@
1
+ 'use strict'
2
+
3
+ const SemVer = require('../classes/semver')
4
+ const Range = require('../classes/range')
5
+
6
+ const maxSatisfying = (versions, range, options) => {
7
+ let max = null
8
+ let maxSV = null
9
+ let rangeObj = null
10
+ try {
11
+ rangeObj = new Range(range, options)
12
+ } catch (er) {
13
+ return null
14
+ }
15
+ versions.forEach((v) => {
16
+ if (rangeObj.test(v)) {
17
+ // satisfies(v, range, options)
18
+ if (!max || maxSV.compare(v) === -1) {
19
+ // compare(max, v, true)
20
+ max = v
21
+ maxSV = new SemVer(max, options)
22
+ }
23
+ }
24
+ })
25
+ return max
26
+ }
27
+ module.exports = maxSatisfying
@@ -0,0 +1,26 @@
1
+ 'use strict'
2
+
3
+ const SemVer = require('../classes/semver')
4
+ const Range = require('../classes/range')
5
+ const minSatisfying = (versions, range, options) => {
6
+ let min = null
7
+ let minSV = null
8
+ let rangeObj = null
9
+ try {
10
+ rangeObj = new Range(range, options)
11
+ } catch (er) {
12
+ return null
13
+ }
14
+ versions.forEach((v) => {
15
+ if (rangeObj.test(v)) {
16
+ // satisfies(v, range, options)
17
+ if (!min || minSV.compare(v) === 1) {
18
+ // compare(min, v, true)
19
+ min = v
20
+ minSV = new SemVer(min, options)
21
+ }
22
+ }
23
+ })
24
+ return min
25
+ }
26
+ module.exports = minSatisfying
@@ -0,0 +1,63 @@
1
+ 'use strict'
2
+
3
+ const SemVer = require('../classes/semver')
4
+ const Range = require('../classes/range')
5
+ const gt = require('../functions/gt')
6
+
7
+ const minVersion = (range, loose) => {
8
+ range = new Range(range, loose)
9
+
10
+ let minver = new SemVer('0.0.0')
11
+ if (range.test(minver)) {
12
+ return minver
13
+ }
14
+
15
+ minver = new SemVer('0.0.0-0')
16
+ if (range.test(minver)) {
17
+ return minver
18
+ }
19
+
20
+ minver = null
21
+ for (let i = 0; i < range.set.length; ++i) {
22
+ const comparators = range.set[i]
23
+
24
+ let setMin = null
25
+ comparators.forEach((comparator) => {
26
+ // Clone to avoid manipulating the comparator's semver object.
27
+ const compver = new SemVer(comparator.semver.version)
28
+ switch (comparator.operator) {
29
+ case '>':
30
+ if (compver.prerelease.length === 0) {
31
+ compver.patch++
32
+ } else {
33
+ compver.prerelease.push(0)
34
+ }
35
+ compver.raw = compver.format()
36
+ /* fallthrough */
37
+ case '':
38
+ case '>=':
39
+ if (!setMin || gt(compver, setMin)) {
40
+ setMin = compver
41
+ }
42
+ break
43
+ case '<':
44
+ case '<=':
45
+ /* Ignore maximum versions */
46
+ break
47
+ /* istanbul ignore next */
48
+ default:
49
+ throw new Error(`Unexpected operation: ${comparator.operator}`)
50
+ }
51
+ })
52
+ if (setMin && (!minver || gt(minver, setMin))) {
53
+ minver = setMin
54
+ }
55
+ }
56
+
57
+ if (minver && range.test(minver)) {
58
+ return minver
59
+ }
60
+
61
+ return null
62
+ }
63
+ module.exports = minVersion
@@ -0,0 +1,82 @@
1
+ 'use strict'
2
+
3
+ const SemVer = require('../classes/semver')
4
+ const Comparator = require('../classes/comparator')
5
+ const { ANY } = Comparator
6
+ const Range = require('../classes/range')
7
+ const satisfies = require('../functions/satisfies')
8
+ const gt = require('../functions/gt')
9
+ const lt = require('../functions/lt')
10
+ const lte = require('../functions/lte')
11
+ const gte = require('../functions/gte')
12
+
13
+ const outside = (version, range, hilo, options) => {
14
+ version = new SemVer(version, options)
15
+ range = new Range(range, options)
16
+
17
+ let gtfn, ltefn, ltfn, comp, ecomp
18
+ switch (hilo) {
19
+ case '>':
20
+ gtfn = gt
21
+ ltefn = lte
22
+ ltfn = lt
23
+ comp = '>'
24
+ ecomp = '>='
25
+ break
26
+ case '<':
27
+ gtfn = lt
28
+ ltefn = gte
29
+ ltfn = gt
30
+ comp = '<'
31
+ ecomp = '<='
32
+ break
33
+ default:
34
+ throw new TypeError('Must provide a hilo val of "<" or ">"')
35
+ }
36
+
37
+ // If it satisfies the range it is not outside
38
+ if (satisfies(version, range, options)) {
39
+ return false
40
+ }
41
+
42
+ // From now on, variable terms are as if we're in "gtr" mode.
43
+ // but note that everything is flipped for the "ltr" function.
44
+
45
+ for (let i = 0; i < range.set.length; ++i) {
46
+ const comparators = range.set[i]
47
+
48
+ let high = null
49
+ let low = null
50
+
51
+ comparators.forEach((comparator) => {
52
+ if (comparator.semver === ANY) {
53
+ comparator = new Comparator('>=0.0.0')
54
+ }
55
+ high = high || comparator
56
+ low = low || comparator
57
+ if (gtfn(comparator.semver, high.semver, options)) {
58
+ high = comparator
59
+ } else if (ltfn(comparator.semver, low.semver, options)) {
60
+ low = comparator
61
+ }
62
+ })
63
+
64
+ // If the edge version comparator has a operator then our version
65
+ // isn't outside it
66
+ if (high.operator === comp || high.operator === ecomp) {
67
+ return false
68
+ }
69
+
70
+ // If the lowest version comparator has an operator and our version
71
+ // is less than it then it isn't higher than the range
72
+ if ((!low.operator || low.operator === comp) &&
73
+ ltefn(version, low.semver)) {
74
+ return false
75
+ } else if (low.operator === ecomp && ltfn(version, low.semver)) {
76
+ return false
77
+ }
78
+ }
79
+ return true
80
+ }
81
+
82
+ module.exports = outside
@@ -0,0 +1,49 @@
1
+ 'use strict'
2
+
3
+ // given a set of versions and a range, create a "simplified" range
4
+ // that includes the same versions that the original range does
5
+ // If the original range is shorter than the simplified one, return that.
6
+ const satisfies = require('../functions/satisfies.js')
7
+ const compare = require('../functions/compare.js')
8
+ module.exports = (versions, range, options) => {
9
+ const set = []
10
+ let first = null
11
+ let prev = null
12
+ const v = versions.sort((a, b) => compare(a, b, options))
13
+ for (const version of v) {
14
+ const included = satisfies(version, range, options)
15
+ if (included) {
16
+ prev = version
17
+ if (!first) {
18
+ first = version
19
+ }
20
+ } else {
21
+ if (prev) {
22
+ set.push([first, prev])
23
+ }
24
+ prev = null
25
+ first = null
26
+ }
27
+ }
28
+ if (first) {
29
+ set.push([first, null])
30
+ }
31
+
32
+ const ranges = []
33
+ for (const [min, max] of set) {
34
+ if (min === max) {
35
+ ranges.push(min)
36
+ } else if (!max && min === v[0]) {
37
+ ranges.push('*')
38
+ } else if (!max) {
39
+ ranges.push(`>=${min}`)
40
+ } else if (min === v[0]) {
41
+ ranges.push(`<=${max}`)
42
+ } else {
43
+ ranges.push(`${min} - ${max}`)
44
+ }
45
+ }
46
+ const simplified = ranges.join(' || ')
47
+ const original = typeof range.raw === 'string' ? range.raw : String(range)
48
+ return simplified.length < original.length ? simplified : range
49
+ }
@@ -0,0 +1,249 @@
1
+ 'use strict'
2
+
3
+ const Range = require('../classes/range.js')
4
+ const Comparator = require('../classes/comparator.js')
5
+ const { ANY } = Comparator
6
+ const satisfies = require('../functions/satisfies.js')
7
+ const compare = require('../functions/compare.js')
8
+
9
+ // Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff:
10
+ // - Every simple range `r1, r2, ...` is a null set, OR
11
+ // - Every simple range `r1, r2, ...` which is not a null set is a subset of
12
+ // some `R1, R2, ...`
13
+ //
14
+ // Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff:
15
+ // - If c is only the ANY comparator
16
+ // - If C is only the ANY comparator, return true
17
+ // - Else if in prerelease mode, return false
18
+ // - else replace c with `[>=0.0.0]`
19
+ // - If C is only the ANY comparator
20
+ // - if in prerelease mode, return true
21
+ // - else replace C with `[>=0.0.0]`
22
+ // - Let EQ be the set of = comparators in c
23
+ // - If EQ is more than one, return true (null set)
24
+ // - Let GT be the highest > or >= comparator in c
25
+ // - Let LT be the lowest < or <= comparator in c
26
+ // - If GT and LT, and GT.semver > LT.semver, return true (null set)
27
+ // - If any C is a = range, and GT or LT are set, return false
28
+ // - If EQ
29
+ // - If GT, and EQ does not satisfy GT, return true (null set)
30
+ // - If LT, and EQ does not satisfy LT, return true (null set)
31
+ // - If EQ satisfies every C, return true
32
+ // - Else return false
33
+ // - If GT
34
+ // - If GT.semver is lower than any > or >= comp in C, return false
35
+ // - If GT is >=, and GT.semver does not satisfy every C, return false
36
+ // - If GT.semver has a prerelease, and not in prerelease mode
37
+ // - If no C has a prerelease and the GT.semver tuple, return false
38
+ // - If LT
39
+ // - If LT.semver is greater than any < or <= comp in C, return false
40
+ // - If LT is <=, and LT.semver does not satisfy every C, return false
41
+ // - If LT.semver has a prerelease, and not in prerelease mode
42
+ // - If no C has a prerelease and the LT.semver tuple, return false
43
+ // - Else return true
44
+
45
+ const subset = (sub, dom, options = {}) => {
46
+ if (sub === dom) {
47
+ return true
48
+ }
49
+
50
+ sub = new Range(sub, options)
51
+ dom = new Range(dom, options)
52
+ let sawNonNull = false
53
+
54
+ OUTER: for (const simpleSub of sub.set) {
55
+ for (const simpleDom of dom.set) {
56
+ const isSub = simpleSubset(simpleSub, simpleDom, options)
57
+ sawNonNull = sawNonNull || isSub !== null
58
+ if (isSub) {
59
+ continue OUTER
60
+ }
61
+ }
62
+ // the null set is a subset of everything, but null simple ranges in
63
+ // a complex range should be ignored. so if we saw a non-null range,
64
+ // then we know this isn't a subset, but if EVERY simple range was null,
65
+ // then it is a subset.
66
+ if (sawNonNull) {
67
+ return false
68
+ }
69
+ }
70
+ return true
71
+ }
72
+
73
+ const minimumVersionWithPreRelease = [new Comparator('>=0.0.0-0')]
74
+ const minimumVersion = [new Comparator('>=0.0.0')]
75
+
76
+ const simpleSubset = (sub, dom, options) => {
77
+ if (sub === dom) {
78
+ return true
79
+ }
80
+
81
+ if (sub.length === 1 && sub[0].semver === ANY) {
82
+ if (dom.length === 1 && dom[0].semver === ANY) {
83
+ return true
84
+ } else if (options.includePrerelease) {
85
+ sub = minimumVersionWithPreRelease
86
+ } else {
87
+ sub = minimumVersion
88
+ }
89
+ }
90
+
91
+ if (dom.length === 1 && dom[0].semver === ANY) {
92
+ if (options.includePrerelease) {
93
+ return true
94
+ } else {
95
+ dom = minimumVersion
96
+ }
97
+ }
98
+
99
+ const eqSet = new Set()
100
+ let gt, lt
101
+ for (const c of sub) {
102
+ if (c.operator === '>' || c.operator === '>=') {
103
+ gt = higherGT(gt, c, options)
104
+ } else if (c.operator === '<' || c.operator === '<=') {
105
+ lt = lowerLT(lt, c, options)
106
+ } else {
107
+ eqSet.add(c.semver)
108
+ }
109
+ }
110
+
111
+ if (eqSet.size > 1) {
112
+ return null
113
+ }
114
+
115
+ let gtltComp
116
+ if (gt && lt) {
117
+ gtltComp = compare(gt.semver, lt.semver, options)
118
+ if (gtltComp > 0) {
119
+ return null
120
+ } else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) {
121
+ return null
122
+ }
123
+ }
124
+
125
+ // will iterate one or zero times
126
+ for (const eq of eqSet) {
127
+ if (gt && !satisfies(eq, String(gt), options)) {
128
+ return null
129
+ }
130
+
131
+ if (lt && !satisfies(eq, String(lt), options)) {
132
+ return null
133
+ }
134
+
135
+ for (const c of dom) {
136
+ if (!satisfies(eq, String(c), options)) {
137
+ return false
138
+ }
139
+ }
140
+
141
+ return true
142
+ }
143
+
144
+ let higher, lower
145
+ let hasDomLT, hasDomGT
146
+ // if the subset has a prerelease, we need a comparator in the superset
147
+ // with the same tuple and a prerelease, or it's not a subset
148
+ let needDomLTPre = lt &&
149
+ !options.includePrerelease &&
150
+ lt.semver.prerelease.length ? lt.semver : false
151
+ let needDomGTPre = gt &&
152
+ !options.includePrerelease &&
153
+ gt.semver.prerelease.length ? gt.semver : false
154
+ // exception: <1.2.3-0 is the same as <1.2.3
155
+ if (needDomLTPre && needDomLTPre.prerelease.length === 1 &&
156
+ lt.operator === '<' && needDomLTPre.prerelease[0] === 0) {
157
+ needDomLTPre = false
158
+ }
159
+
160
+ for (const c of dom) {
161
+ hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>='
162
+ hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<='
163
+ if (gt) {
164
+ if (needDomGTPre) {
165
+ if (c.semver.prerelease && c.semver.prerelease.length &&
166
+ c.semver.major === needDomGTPre.major &&
167
+ c.semver.minor === needDomGTPre.minor &&
168
+ c.semver.patch === needDomGTPre.patch) {
169
+ needDomGTPre = false
170
+ }
171
+ }
172
+ if (c.operator === '>' || c.operator === '>=') {
173
+ higher = higherGT(gt, c, options)
174
+ if (higher === c && higher !== gt) {
175
+ return false
176
+ }
177
+ } else if (gt.operator === '>=' && !c.test(gt.semver)) {
178
+ return false
179
+ }
180
+ }
181
+ if (lt) {
182
+ if (needDomLTPre) {
183
+ if (c.semver.prerelease && c.semver.prerelease.length &&
184
+ c.semver.major === needDomLTPre.major &&
185
+ c.semver.minor === needDomLTPre.minor &&
186
+ c.semver.patch === needDomLTPre.patch) {
187
+ needDomLTPre = false
188
+ }
189
+ }
190
+ if (c.operator === '<' || c.operator === '<=') {
191
+ lower = lowerLT(lt, c, options)
192
+ if (lower === c && lower !== lt) {
193
+ return false
194
+ }
195
+ } else if (lt.operator === '<=' && !c.test(lt.semver)) {
196
+ return false
197
+ }
198
+ }
199
+ if (!c.operator && (lt || gt) && gtltComp !== 0) {
200
+ return false
201
+ }
202
+ }
203
+
204
+ // if there was a < or >, and nothing in the dom, then must be false
205
+ // UNLESS it was limited by another range in the other direction.
206
+ // Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0
207
+ if (gt && hasDomLT && !lt && gtltComp !== 0) {
208
+ return false
209
+ }
210
+
211
+ if (lt && hasDomGT && !gt && gtltComp !== 0) {
212
+ return false
213
+ }
214
+
215
+ // we needed a prerelease range in a specific tuple, but didn't get one
216
+ // then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0,
217
+ // because it includes prereleases in the 1.2.3 tuple
218
+ if (needDomGTPre || needDomLTPre) {
219
+ return false
220
+ }
221
+
222
+ return true
223
+ }
224
+
225
+ // >=1.2.3 is lower than >1.2.3
226
+ const higherGT = (a, b, options) => {
227
+ if (!a) {
228
+ return b
229
+ }
230
+ const comp = compare(a.semver, b.semver, options)
231
+ return comp > 0 ? a
232
+ : comp < 0 ? b
233
+ : b.operator === '>' && a.operator === '>=' ? b
234
+ : a
235
+ }
236
+
237
+ // <=1.2.3 is higher than <1.2.3
238
+ const lowerLT = (a, b, options) => {
239
+ if (!a) {
240
+ return b
241
+ }
242
+ const comp = compare(a.semver, b.semver, options)
243
+ return comp < 0 ? a
244
+ : comp > 0 ? b
245
+ : b.operator === '<' && a.operator === '<=' ? b
246
+ : a
247
+ }
248
+
249
+ module.exports = subset
@@ -0,0 +1,10 @@
1
+ 'use strict'
2
+
3
+ const Range = require('../classes/range')
4
+
5
+ // Mostly just for testing and legacy API reasons
6
+ const toComparators = (range, options) =>
7
+ new Range(range, options).set
8
+ .map(comp => comp.map(c => c.value).join(' ').trim().split(' '))
9
+
10
+ module.exports = toComparators
@@ -0,0 +1,13 @@
1
+ 'use strict'
2
+
3
+ const Range = require('../classes/range')
4
+ const validRange = (range, options) => {
5
+ try {
6
+ // Return '*' instead of '' so that truthiness works.
7
+ // This will throw if it's invalid anyway
8
+ return new Range(range, options).range || '*'
9
+ } catch (er) {
10
+ return null
11
+ }
12
+ }
13
+ module.exports = validRange
@@ -6,6 +6,11 @@
6
6
 
7
7
  This npm module implements the base messaging protocol spoken between a VSCode language server and a VSCode language client.
8
8
 
9
+ The Node.js entry point requires Node.js 14.17.0 or newer. The runtime abstraction layer exposes
10
+ `RAL().crypto.randomUUID()` for cryptographically generated v4 UUIDs. The browser implementation
11
+ uses native `crypto.randomUUID()` when available and falls back to `crypto.getRandomValues()`,
12
+ including in non-secure contexts. Custom RAL implementations must provide this capability.
13
+
9
14
  The npm module can also be used standalone to establish a [JSON-RPC](http://www.jsonrpc.org/) channel between
10
15
  a client and a server. Below an example how to setup a JSON-RPC connection. First the client side.
11
16
 
@@ -145,6 +145,14 @@ class PromiseImpl {
145
145
  exports.PromiseImpl = PromiseImpl;
146
146
  const _textEncoder = new TextEncoder();
147
147
  const _ril = Object.freeze({
148
+ crypto: Object.freeze({
149
+ randomUUID() {
150
+ if (typeof globalThis.crypto.randomUUID === 'function') {
151
+ return globalThis.crypto.randomUUID();
152
+ }
153
+ return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, c => (+c ^ (globalThis.crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (+c / 4)))).toString(16));
154
+ }
155
+ }),
148
156
  messageBuffer: Object.freeze({
149
157
  create: (encoding) => new MessageBuffer(encoding)
150
158
  }),
@@ -418,11 +418,16 @@ function createMessageConnection(messageReader, messageWriter, _logger, options)
418
418
  }
419
419
  finally {
420
420
  if (result instanceof Promise) {
421
+ // Both settlements must release the parallelism slot. Written as
422
+ // .then(...).catch(...) the rejection path skipped the decrement, so
423
+ // one failed dispatch left `inFlight` permanently elevated and
424
+ // triggerMessageQueue() bailed out forever after.
421
425
  result.then(() => {
422
- inFlight--;
423
- triggerMessageQueue();
424
426
  }).catch((error) => {
425
427
  logger.error(`Processing message queue failed: ${error.toString()}`);
428
+ }).finally(() => {
429
+ inFlight--;
430
+ triggerMessageQueue();
426
431
  });
427
432
  }
428
433
  else {
@@ -42,7 +42,15 @@ interface _WritableStream {
42
42
  }
43
43
  interface _DuplexStream extends _ReadableStream, _WritableStream {
44
44
  }
45
+ /**
46
+ * Runtime abstraction implemented by this npm module.
47
+ * External implementations are not supported. Changes to this interface do not
48
+ * require a major version bump.
49
+ */
45
50
  interface RAL {
51
+ readonly crypto: {
52
+ randomUUID(): string;
53
+ };
46
54
  readonly applicationJson: {
47
55
  readonly encoder: ContentTypeEncoder;
48
56
  readonly decoder: ContentTypeDecoder;
@@ -46,12 +46,26 @@ export declare class StreamMessageWriter extends WriteableStreamMessageWriter {
46
46
  export declare function generateRandomPipeName(): string;
47
47
  export interface PipeTransport {
48
48
  onConnected(): Promise<[MessageReader, MessageWriter]>;
49
+ /**
50
+ * Closes the underlying server if a client hasn't connected yet. Callers
51
+ * should invoke this if they abandon the transport before `onConnected`
52
+ * resolves (for example because the server process failed to start) to
53
+ * avoid leaking the listening pipe.
54
+ */
55
+ close(): void;
49
56
  }
50
57
  export declare function createClientPipeTransport(pipeName: string, encoding?: RAL.MessageBufferEncoding): Promise<PipeTransport>;
51
58
  export declare function createServerPipeTransport(pipeName: string, encoding?: RAL.MessageBufferEncoding): [MessageReader, MessageWriter];
52
59
  export interface SocketTransport {
53
60
  port(): number;
54
61
  onConnected(): Promise<[MessageReader, MessageWriter]>;
62
+ /**
63
+ * Closes the underlying server if a client hasn't connected yet. Callers
64
+ * should invoke this if they abandon the transport before `onConnected`
65
+ * resolves (for example because the server process failed to start) to
66
+ * avoid leaking the listening socket.
67
+ */
68
+ close(): void;
55
69
  }
56
70
  export declare function createClientSocketTransport(port: number, encoding?: RAL.MessageBufferEncoding): Promise<SocketTransport>;
57
71
  export declare function createServerSocketTransport(port: number, encoding?: RAL.MessageBufferEncoding): [MessageReader, MessageWriter];
@@ -84,7 +84,7 @@ class IPCMessageWriter extends api_1.AbstractMessageWriter {
84
84
  this.errorCount = 0;
85
85
  const eventEmitter = this.process;
86
86
  eventEmitter.on('error', (error) => this.fireError(error));
87
- eventEmitter.on('close', () => this.fireClose);
87
+ eventEmitter.on('close', () => this.fireClose());
88
88
  }
89
89
  write(msg) {
90
90
  try {
@@ -119,7 +119,7 @@ class PortMessageReader extends api_1.AbstractMessageReader {
119
119
  constructor(port) {
120
120
  super();
121
121
  this.onData = new api_1.Emitter;
122
- port.on('close', () => this.fireClose);
122
+ port.on('close', () => this.fireClose());
123
123
  port.on('error', (error) => this.fireError(error));
124
124
  port.on('message', (message) => {
125
125
  this.onData.fire(message);
@@ -227,7 +227,8 @@ function createClientPipeTransport(pipeName, encoding = 'utf-8') {
227
227
  server.listen(pipeName, () => {
228
228
  server.removeListener('error', reject);
229
229
  resolve({
230
- onConnected: () => { return connected; }
230
+ onConnected: () => { return connected; },
231
+ close: () => { server.close(); }
231
232
  });
232
233
  });
233
234
  });
@@ -263,7 +264,8 @@ function createClientSocketTransport(port, encoding = 'utf-8') {
263
264
  const boundPort = address.port;
264
265
  resolve({
265
266
  port: () => boundPort,
266
- onConnected: () => { return connected; }
267
+ onConnected: () => { return connected; },
268
+ close: () => { server.close(); }
267
269
  });
268
270
  });
269
271
  });
@@ -5,6 +5,7 @@
5
5
  * ------------------------------------------------------------------------------------------ */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const util_1 = require("util");
8
+ const crypto_1 = require("crypto");
8
9
  const api_1 = require("../common/api");
9
10
  class MessageBuffer extends api_1.AbstractMessageBuffer {
10
11
  static emptyBuffer = Buffer.allocUnsafe(0);
@@ -30,7 +31,7 @@ class MessageBuffer extends api_1.AbstractMessageBuffer {
30
31
  return buffer instanceof Buffer ? buffer : Buffer.from(buffer);
31
32
  }
32
33
  else {
33
- return buffer instanceof Buffer ? buffer.slice(0, length) : Buffer.from(buffer, 0, length);
34
+ return buffer instanceof Buffer ? buffer.slice(0, length) : Buffer.from(buffer.subarray(0, length));
34
35
  }
35
36
  }
36
37
  allocNative(length) {
@@ -99,6 +100,9 @@ class WritableStreamWrapper {
99
100
  }
100
101
  }
101
102
  const _ril = Object.freeze({
103
+ crypto: Object.freeze({
104
+ randomUUID: () => (0, crypto_1.randomUUID)()
105
+ }),
102
106
  messageBuffer: Object.freeze({
103
107
  create: (encoding) => new MessageBuffer(encoding)
104
108
  }),