@endo/compartment-mapper 2.0.0 → 2.1.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/package.json +23 -9
- package/src/archive-lite.js +3 -3
- package/src/capture-lite.d.ts.map +1 -1
- package/src/capture-lite.js +29 -3
- package/src/compartment-map.d.ts.map +1 -1
- package/src/compartment-map.js +3 -2
- package/src/digest.js +1 -1
- package/src/generic-graph.d.ts +7 -25
- package/src/generic-graph.d.ts.map +1 -1
- package/src/generic-graph.js +75 -105
- package/src/import-hook.d.ts.map +1 -1
- package/src/import-hook.js +4 -3
- package/src/infer-exports.d.ts +4 -2
- package/src/infer-exports.d.ts.map +1 -1
- package/src/infer-exports.js +158 -19
- package/src/link.d.ts.map +1 -1
- package/src/link.js +61 -3
- package/src/node-modules.d.ts.map +1 -1
- package/src/node-modules.js +33 -39
- package/src/pattern-replacement.d.ts +6 -0
- package/src/pattern-replacement.d.ts.map +1 -0
- package/src/pattern-replacement.js +198 -0
- package/src/types/compartment-map-schema.d.ts +8 -1
- package/src/types/compartment-map-schema.d.ts.map +1 -1
- package/src/types/compartment-map-schema.ts +9 -0
- package/src/types/external.d.ts +79 -55
- package/src/types/external.d.ts.map +1 -1
- package/src/types/external.ts +104 -62
- package/src/types/generic-graph.d.ts +8 -2
- package/src/types/generic-graph.d.ts.map +1 -1
- package/src/types/generic-graph.ts +7 -2
- package/src/types/internal.d.ts +8 -8
- package/src/types/internal.d.ts.map +1 -1
- package/src/types/internal.ts +9 -8
- package/src/types/node-modules.d.ts +45 -8
- package/src/types/node-modules.d.ts.map +1 -1
- package/src/types/node-modules.ts +56 -15
- package/src/types/pattern-replacement.d.ts +62 -0
- package/src/types/pattern-replacement.d.ts.map +1 -0
- package/src/types/pattern-replacement.ts +70 -0
- package/src/types/powers.d.ts +11 -9
- package/src/types/powers.d.ts.map +1 -1
- package/src/types/powers.ts +11 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@endo/compartment-mapper",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "The compartment mapper assembles Node applications in a sandbox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node",
|
|
@@ -49,31 +49,41 @@
|
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "exit 0",
|
|
52
|
-
"prepack": "tsc --build tsconfig.build.json",
|
|
53
|
-
"postpack": "git clean -fX
|
|
52
|
+
"prepack": "git clean -fX -e node_modules/ && tsc --build tsconfig.build.json",
|
|
53
|
+
"postpack": "git clean -fX -e node_modules/",
|
|
54
54
|
"cover": "c8 ava --config test/_ava-ses.config.js",
|
|
55
55
|
"lint": "yarn lint:types && yarn lint:eslint",
|
|
56
56
|
"lint-fix": "eslint --fix .",
|
|
57
57
|
"lint:eslint": "eslint .",
|
|
58
58
|
"lint:types": "tsc",
|
|
59
59
|
"prettier-fixtures": "prettier --write --with-node-modules './test/fixtures-*/**/*.*js'",
|
|
60
|
-
"test": "ava"
|
|
60
|
+
"test": "ses-ava"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@endo/cjs-module-analyzer": "^1.0.11",
|
|
64
|
-
"@endo/module-source": "^1.4.
|
|
64
|
+
"@endo/module-source": "^1.4.1",
|
|
65
65
|
"@endo/path-compare": "^1.1.0",
|
|
66
66
|
"@endo/trampoline": "^1.0.5",
|
|
67
67
|
"@endo/zip": "^1.1.0",
|
|
68
|
-
"ses": "^
|
|
68
|
+
"ses": "^2.0.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@endo/env-options": "^1.1.11",
|
|
72
|
+
"@endo/evasive-transform": "^2.1.0",
|
|
73
|
+
"@endo/eventual-send": "^1.5.0",
|
|
72
74
|
"@endo/init": "^1.1.13",
|
|
75
|
+
"@endo/ses-ava": "^1.4.1",
|
|
73
76
|
"ava": "catalog:dev",
|
|
77
|
+
"babel-eslint": "^10.1.0",
|
|
74
78
|
"c8": "catalog:dev",
|
|
75
79
|
"eslint": "catalog:dev",
|
|
76
|
-
"
|
|
80
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
81
|
+
"eslint-config-prettier": "^9.1.0",
|
|
82
|
+
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
83
|
+
"eslint-plugin-import": "^2.31.0",
|
|
84
|
+
"prettier": "^3.5.3",
|
|
85
|
+
"ses": "workspace:^",
|
|
86
|
+
"typescript": "catalog:dev"
|
|
77
87
|
},
|
|
78
88
|
"files": [
|
|
79
89
|
"./*.d.ts",
|
|
@@ -108,12 +118,16 @@
|
|
|
108
118
|
},
|
|
109
119
|
"ava": {
|
|
110
120
|
"files": [
|
|
111
|
-
"test/**/*.test.*"
|
|
121
|
+
"test/**/*.test.*",
|
|
122
|
+
"!test/**/*.node-condition.test.*"
|
|
112
123
|
],
|
|
113
124
|
"timeout": "2m"
|
|
114
125
|
},
|
|
126
|
+
"sesAvaConfigs": {
|
|
127
|
+
"node-condition": "test/_ava-node-condition.config.js"
|
|
128
|
+
},
|
|
115
129
|
"typeCoverage": {
|
|
116
130
|
"atLeast": 86.14
|
|
117
131
|
},
|
|
118
|
-
"gitHead": "
|
|
132
|
+
"gitHead": "e74ed050e9d1122d692b00ee14971299c6afbf30"
|
|
119
133
|
}
|
package/src/archive-lite.js
CHANGED
|
@@ -255,7 +255,7 @@ const digestFromMap = async (powers, compartmentMap, options = {}) => {
|
|
|
255
255
|
|
|
256
256
|
const archiveCompartmentMapText = JSON.stringify(
|
|
257
257
|
archiveCompartmentMap,
|
|
258
|
-
|
|
258
|
+
(key, value) => (key.startsWith('_') ? undefined : value),
|
|
259
259
|
2,
|
|
260
260
|
);
|
|
261
261
|
const archiveCompartmentMapBytes = textEncoder.encode(
|
|
@@ -274,7 +274,7 @@ const digestFromMap = async (powers, compartmentMap, options = {}) => {
|
|
|
274
274
|
return {
|
|
275
275
|
compartmentMapBytes: archiveCompartmentMapBytes,
|
|
276
276
|
sources: archiveSources,
|
|
277
|
-
sha512: archiveSha512,
|
|
277
|
+
...(archiveSha512 !== undefined && { sha512: archiveSha512 }),
|
|
278
278
|
};
|
|
279
279
|
};
|
|
280
280
|
|
|
@@ -300,7 +300,7 @@ export const makeAndHashArchiveFromMap = async (
|
|
|
300
300
|
await addSourcesToArchive(archive, sources);
|
|
301
301
|
const bytes = await archive.snapshot();
|
|
302
302
|
|
|
303
|
-
return { bytes, sha512 };
|
|
303
|
+
return { bytes, ...(sha512 !== undefined && { sha512 }) };
|
|
304
304
|
};
|
|
305
305
|
|
|
306
306
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture-lite.d.ts","sourceRoot":"","sources":["capture-lite.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"capture-lite.d.ts","sourceRoot":"","sources":["capture-lite.js"],"names":[],"mappings":"AA2RO,2CALI,MAAM,GAAG,UAAU,kBACnB,+BAA+B,YAC/B,kBAAkB,GAChB,OAAO,CAAC,aAAa,CAAC,CAwFlC;4BApUS,YAAY;gCAAZ,YAAY;qDAAZ,YAAY;wCAAZ,YAAY;mCAAZ,YAAY"}
|
package/src/capture-lite.js
CHANGED
|
@@ -112,7 +112,12 @@ const captureCompartmentMap = (
|
|
|
112
112
|
const makePreloader = (
|
|
113
113
|
compartmentMap,
|
|
114
114
|
sources,
|
|
115
|
-
{
|
|
115
|
+
{
|
|
116
|
+
log = noop,
|
|
117
|
+
policy,
|
|
118
|
+
_preload: preload = [],
|
|
119
|
+
_redundantPreloadHook: redundantPreloadHook = undefined,
|
|
120
|
+
} = {},
|
|
116
121
|
) => {
|
|
117
122
|
const {
|
|
118
123
|
entry: { module: entryModuleSpecifier },
|
|
@@ -173,10 +178,29 @@ const makePreloader = (
|
|
|
173
178
|
|
|
174
179
|
const compartmentSources = sources[compartmentName];
|
|
175
180
|
|
|
176
|
-
|
|
181
|
+
// The default preload entry is the entry module as defined by the
|
|
182
|
+
// package itself. This corresponds to the `ModuleConfiguration` of `.`
|
|
183
|
+
// in the `CompartmentDescriptor`'s `modules` object. Since the key in
|
|
184
|
+
// `compartmentSources` is presumably a resolved relative path, we don't
|
|
185
|
+
// actually know which key to look for! Thus, we are assuming that the
|
|
186
|
+
// `Compartment`'s entry module has been loaded if _any_ sources are
|
|
187
|
+
// present.
|
|
188
|
+
const entryIsLoaded =
|
|
189
|
+
entry === DEFAULT_PRELOAD_ENTRY
|
|
190
|
+
? keys(compartmentSources).length > 0
|
|
191
|
+
: entry in compartmentSources;
|
|
192
|
+
|
|
193
|
+
if (entryIsLoaded) {
|
|
177
194
|
log(
|
|
178
|
-
`Refusing to preload Compartment ${q(canonicalName)}; already loaded`,
|
|
195
|
+
`Refusing to preload Compartment ${q(canonicalName)} entry ${q(entry)}; already loaded`,
|
|
179
196
|
);
|
|
197
|
+
if (redundantPreloadHook) {
|
|
198
|
+
redundantPreloadHook({
|
|
199
|
+
canonicalName,
|
|
200
|
+
entry,
|
|
201
|
+
log,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
180
204
|
} else {
|
|
181
205
|
const compartment = compartments[compartmentName];
|
|
182
206
|
if (!compartment) {
|
|
@@ -274,6 +298,7 @@ export const captureFromMap = async (
|
|
|
274
298
|
Compartment: CompartmentOption = DefaultCompartment,
|
|
275
299
|
log = noop,
|
|
276
300
|
_preload: preload = [],
|
|
301
|
+
_redundantPreloadHook: redundantPreloadHook = undefined,
|
|
277
302
|
packageConnectionsHook,
|
|
278
303
|
moduleSourceHook,
|
|
279
304
|
} = options;
|
|
@@ -295,6 +320,7 @@ export const captureFromMap = async (
|
|
|
295
320
|
log,
|
|
296
321
|
policy,
|
|
297
322
|
_preload: preload,
|
|
323
|
+
_redundantPreloadHook: redundantPreloadHook,
|
|
298
324
|
});
|
|
299
325
|
|
|
300
326
|
const consolidatedExitModuleImportHook = exitModuleImportHookMaker({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compartment-map.d.ts","sourceRoot":"","sources":["compartment-map.js"],"names":[],"mappings":"AAyCA,+CAA+C;AAE/C,4BAFW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAE2B;
|
|
1
|
+
{"version":3,"file":"compartment-map.d.ts","sourceRoot":"","sources":["compartment-map.js"],"names":[],"mappings":"AAyCA,+CAA+C;AAE/C,4BAFW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAE2B;AA60B/D,gEAJI,OAAO,QACP,MAAM,GACJ,QAAQ,qBAAqB,IAAI,4BAA4B,CASzE;AAQM,0EAJI,OAAO,QACP,MAAM,GACJ,QAAQ,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAUxF;AAQM,oEAJI,OAAO,QACP,MAAM,GACJ,QAAQ,qBAAqB,IAAI,gCAAgC,CAS7E;AAOM,mEAJI,OAAO,QACP,MAAM,GACJ,QAAQ,qBAAqB,IAAI,+BAA+B,CAS5E;qBApca,CAAC,aACF,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI;kDA3c1B,YAAY;mDAAZ,YAAY;sDAAZ,YAAY;qDAAZ,YAAY"}
|
package/src/compartment-map.js
CHANGED
|
@@ -177,12 +177,13 @@ const assertConditions = (conditions, url) => {
|
|
|
177
177
|
*/
|
|
178
178
|
const getModuleConfigurationSpecificProperties = allegedModule => {
|
|
179
179
|
const {
|
|
180
|
-
__createdBy: _createdBy,
|
|
181
180
|
retained: _retained,
|
|
182
181
|
deferredError: _deferredError,
|
|
183
182
|
...other
|
|
184
183
|
} = allegedModule;
|
|
185
|
-
return
|
|
184
|
+
return /** @type {Omit<T, keyof BaseModuleConfiguration>} */ (
|
|
185
|
+
Object.fromEntries(entries(other).filter(([key]) => !key.startsWith('_')))
|
|
186
|
+
);
|
|
186
187
|
};
|
|
187
188
|
|
|
188
189
|
/**
|
package/src/digest.js
CHANGED
package/src/generic-graph.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* A generic graph implementation.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Edge weights are assumed to be non-negative numbers (including `Infinity`)
|
|
4
|
+
* @template {GenericGraphNode} [T=string] The type of nodes in the graph. If
|
|
5
|
+
* `T` is not a string, relative paths will be compared by coercion to strings.
|
|
7
6
|
*/
|
|
8
|
-
export class GenericGraph<T = string> {
|
|
7
|
+
export class GenericGraph<T extends GenericGraphNode = string> {
|
|
9
8
|
/**
|
|
10
9
|
* Returns a shallow copy of the `Set` of nodes in the graph.
|
|
11
10
|
*/
|
|
@@ -31,23 +30,6 @@ export class GenericGraph<T = string> {
|
|
|
31
30
|
* @returns {Set<T>|undefined}
|
|
32
31
|
*/
|
|
33
32
|
adjacent(node: T): Set<T> | undefined;
|
|
34
|
-
/**
|
|
35
|
-
* Sets the weight of the given edge between `source` and `target`.
|
|
36
|
-
*
|
|
37
|
-
* @param {T} source Source node
|
|
38
|
-
* @param {T} target Target node
|
|
39
|
-
* @param {number} weight New edge weight
|
|
40
|
-
* @returns {this}
|
|
41
|
-
*/
|
|
42
|
-
setEdgeWeight(source: T, target: T, weight: number): this;
|
|
43
|
-
/**
|
|
44
|
-
* Gets the weight of the given edge between `source` and `target`.
|
|
45
|
-
*
|
|
46
|
-
* @param {T} source Source node
|
|
47
|
-
* @param {T} target Target node
|
|
48
|
-
* @returns {number} Edge weight from source to target
|
|
49
|
-
*/
|
|
50
|
-
getEdgeWeight(source: T, target: T): number;
|
|
51
33
|
/**
|
|
52
34
|
* Adds an edge from the `source` node to `target` node.
|
|
53
35
|
*
|
|
@@ -58,10 +40,9 @@ export class GenericGraph<T = string> {
|
|
|
58
40
|
*
|
|
59
41
|
* @param {T} source Source node
|
|
60
42
|
* @param {T} target Target node
|
|
61
|
-
* @param {number} weight Edge weight from source to target
|
|
62
43
|
* @returns {this} This graph instance
|
|
63
44
|
*/
|
|
64
|
-
addEdge(source: T, target: T
|
|
45
|
+
addEdge(source: T, target: T): this;
|
|
65
46
|
/**
|
|
66
47
|
* Removes the edge from the `source` node to `target` node.
|
|
67
48
|
* Does not remove the nodes themselves.
|
|
@@ -80,5 +61,6 @@ export class GenericGraph<T = string> {
|
|
|
80
61
|
hasEdge(source: T, target: T): boolean;
|
|
81
62
|
#private;
|
|
82
63
|
}
|
|
83
|
-
export function makeShortestPath<T = string>(graph: GenericGraph<T>): (source: NoInfer<T>, target: NoInfer<T>) => [T, T, ...T[]];
|
|
64
|
+
export function makeShortestPath<T extends GenericGraphNode = string>(graph: GenericGraph<T>): (source: NoInfer<T>, target: NoInfer<T>) => [T, T, ...T[]];
|
|
65
|
+
import type { GenericGraphNode } from './types/generic-graph.js';
|
|
84
66
|
//# sourceMappingURL=generic-graph.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic-graph.d.ts","sourceRoot":"","sources":["generic-graph.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generic-graph.d.ts","sourceRoot":"","sources":["generic-graph.js"],"names":[],"mappings":"AAsIA;;;;;GAKG;AACH,0BAHiC,CAAC,SAArB,gBAAkB;IAsB7B;;OAEG;IACH,oBAEC;IAED;;;;;;OAMG;IACH,cAHW,CAAC,GACC,IAAI,CAUhB;IAED;;;;;OAKG;IACH,iBAHW,CAAC,GACC,IAAI,CAShB;IAED;;;;OAIG;IACH,eAHW,CAAC,GACC,GAAG,CAAC,CAAC,CAAC,GAAC,SAAS,CAI5B;IAED;;;;;;;;;;;OAWG;IACH,gBAJW,CAAC,UACD,CAAC,GACC,IAAI,CAUhB;IAED;;;;;;;OAOG;IACH,mBAJW,CAAC,UACD,CAAC,GACC,IAAI,CAKhB;IAED;;;;;OAKG;IACH,gBAJW,CAAC,UACD,CAAC,GACC,OAAO,CAInB;;CACF;AAwDM,iCAH0B,CAAC,SAArB,gBAAkB,kBACpB,YAAY,CAAC,CAAC,CAAC,YAOb,OAAO,CAAC,CAAC,CAAC,UACV,OAAO,CAAC,CAAC,CAAC,KACR,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAW5B;sCAvToD,0BAA0B"}
|
package/src/generic-graph.js
CHANGED
|
@@ -9,31 +9,49 @@
|
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { pathCompare } from '@endo/path-compare';
|
|
13
|
+
|
|
12
14
|
/**
|
|
13
|
-
* @import {TraversalContext} from './types/generic-graph.js';
|
|
15
|
+
* @import {GenericGraphNode, TraversalContext} from './types/generic-graph.js';
|
|
14
16
|
*/
|
|
15
17
|
|
|
16
18
|
const { quote: q } = assert;
|
|
17
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Returns `true` if the cost of path `a` is less than the cost of path `b`.
|
|
22
|
+
*
|
|
23
|
+
* @template {GenericGraphNode} [T=string]
|
|
24
|
+
* @param {T[]} [pathA]
|
|
25
|
+
* @param {T[]} [pathB]
|
|
26
|
+
* @returns {boolean}
|
|
27
|
+
*/
|
|
28
|
+
const isLowerCost = (pathA, pathB) =>
|
|
29
|
+
pathCompare(pathA?.map(String), pathB?.map(String)) < 0;
|
|
30
|
+
|
|
18
31
|
/**
|
|
19
32
|
* Remove the node with the minimum weight from the priority queue.
|
|
20
33
|
*
|
|
21
34
|
* Performs linear search.
|
|
22
|
-
*
|
|
35
|
+
*
|
|
36
|
+
* @template {GenericGraphNode} [T=string]
|
|
23
37
|
* @param {TraversalContext<T>} tracks
|
|
24
38
|
* @returns {T|undefined}
|
|
25
39
|
*/
|
|
26
|
-
const extractMin = ({
|
|
27
|
-
|
|
40
|
+
const extractMin = ({ paths, queue }) => {
|
|
41
|
+
/** @type {T[]|undefined} */
|
|
42
|
+
let minPath;
|
|
28
43
|
|
|
29
44
|
/** @type {T|undefined} */
|
|
30
45
|
let minNode;
|
|
31
46
|
|
|
32
47
|
queue.forEach(node => {
|
|
33
|
-
const
|
|
48
|
+
const path = paths.get(node);
|
|
49
|
+
if (!path) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
34
52
|
|
|
35
|
-
if (
|
|
36
|
-
|
|
53
|
+
if (!minPath || isLowerCost(path, minPath)) {
|
|
54
|
+
minPath = path;
|
|
37
55
|
minNode = node;
|
|
38
56
|
}
|
|
39
57
|
});
|
|
@@ -48,32 +66,23 @@ const extractMin = ({ distances, queue }) => {
|
|
|
48
66
|
};
|
|
49
67
|
|
|
50
68
|
/**
|
|
51
|
-
* Update context
|
|
52
|
-
*
|
|
69
|
+
* Update context to include the current lowest-cost path to a target node
|
|
70
|
+
* reachable by a single edge from a source node.
|
|
53
71
|
*
|
|
54
|
-
* @template [T=string]
|
|
55
|
-
* @param {
|
|
56
|
-
* @param {TraversalContext<NoInfer<T>>} context
|
|
72
|
+
* @template {GenericGraphNode} [T=string]
|
|
73
|
+
* @param {TraversalContext<T>} context
|
|
57
74
|
* @param {NoInfer<T>} source
|
|
58
75
|
* @param {NoInfer<T>} target
|
|
59
76
|
*/
|
|
60
|
-
const relax = (
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
const distanceSource = distances.get(source);
|
|
64
|
-
const distanceTarget = distances.get(target);
|
|
77
|
+
const relax = ({ paths, predecessors }, source, target) => {
|
|
78
|
+
const pathSource = paths.get(source);
|
|
79
|
+
assert(pathSource, `Missing path to source ${q(source)}`);
|
|
65
80
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
`Missing distance for source ${q(source)}`,
|
|
69
|
-
);
|
|
70
|
-
assert(
|
|
71
|
-
distanceTarget !== undefined,
|
|
72
|
-
`Missing distance for target ${q(target)} target`,
|
|
73
|
-
);
|
|
81
|
+
const pathTarget = paths.get(target);
|
|
82
|
+
const newPath = [...pathSource, target];
|
|
74
83
|
|
|
75
|
-
if (
|
|
76
|
-
|
|
84
|
+
if (!pathTarget || isLowerCost(newPath, pathTarget)) {
|
|
85
|
+
paths.set(target, newPath);
|
|
77
86
|
predecessors.set(target, source);
|
|
78
87
|
}
|
|
79
88
|
};
|
|
@@ -82,7 +91,7 @@ const relax = (graph, { distances, predecessors }, source, target) => {
|
|
|
82
91
|
* Assembles the shortest path by traversing the
|
|
83
92
|
* predecessor subgraph from destination to source.
|
|
84
93
|
*
|
|
85
|
-
* @template [T=string]
|
|
94
|
+
* @template {GenericGraphNode} [T=string]
|
|
86
95
|
* @param {TraversalContext<NoInfer<T>>} context Traversal context object
|
|
87
96
|
* @param {NoInfer<T>} source Source node
|
|
88
97
|
* @param {NoInfer<T>} target Destination node
|
|
@@ -107,7 +116,11 @@ const getPath = ({ predecessors }, source, target) => {
|
|
|
107
116
|
node = currentNode;
|
|
108
117
|
}
|
|
109
118
|
|
|
110
|
-
assert.equal(
|
|
119
|
+
assert.equal(
|
|
120
|
+
node,
|
|
121
|
+
source,
|
|
122
|
+
`No path found from ${q(String(source))} to ${q(String(target))}`,
|
|
123
|
+
);
|
|
111
124
|
|
|
112
125
|
nodeList.push(node);
|
|
113
126
|
|
|
@@ -120,11 +133,10 @@ const getPath = ({ predecessors }, source, target) => {
|
|
|
120
133
|
};
|
|
121
134
|
|
|
122
135
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* A generic graph implementation with edge weights.
|
|
136
|
+
* A generic graph implementation.
|
|
126
137
|
*
|
|
127
|
-
*
|
|
138
|
+
* @template {GenericGraphNode} [T=string] The type of nodes in the graph. If
|
|
139
|
+
* `T` is not a string, relative paths will be compared by coercion to strings.
|
|
128
140
|
*/
|
|
129
141
|
export class GenericGraph {
|
|
130
142
|
/**
|
|
@@ -137,16 +149,10 @@ export class GenericGraph {
|
|
|
137
149
|
*/
|
|
138
150
|
#edges;
|
|
139
151
|
|
|
140
|
-
/**
|
|
141
|
-
* @type {Map<T, Map<T, number>>}
|
|
142
|
-
*/
|
|
143
|
-
#edgeWeights;
|
|
144
|
-
|
|
145
152
|
/**
|
|
146
153
|
* Initializes internal data structures.
|
|
147
154
|
*/
|
|
148
155
|
constructor() {
|
|
149
|
-
this.#edgeWeights = new Map();
|
|
150
156
|
this.#edges = new Map();
|
|
151
157
|
this.#nodes = new Set();
|
|
152
158
|
}
|
|
@@ -199,42 +205,6 @@ export class GenericGraph {
|
|
|
199
205
|
return this.#edges.get(node);
|
|
200
206
|
}
|
|
201
207
|
|
|
202
|
-
/**
|
|
203
|
-
* Sets the weight of the given edge between `source` and `target`.
|
|
204
|
-
*
|
|
205
|
-
* @param {T} source Source node
|
|
206
|
-
* @param {T} target Target node
|
|
207
|
-
* @param {number} weight New edge weight
|
|
208
|
-
* @returns {this}
|
|
209
|
-
*/
|
|
210
|
-
setEdgeWeight(source, target, weight) {
|
|
211
|
-
if (!this.#edgeWeights.has(source)) {
|
|
212
|
-
this.#edgeWeights.set(source, new Map());
|
|
213
|
-
}
|
|
214
|
-
const weights = /** @type {Map<T, number>} */ (
|
|
215
|
-
this.#edgeWeights.get(source)
|
|
216
|
-
);
|
|
217
|
-
weights.set(target, weight);
|
|
218
|
-
return this;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Gets the weight of the given edge between `source` and `target`.
|
|
223
|
-
*
|
|
224
|
-
* @param {T} source Source node
|
|
225
|
-
* @param {T} target Target node
|
|
226
|
-
* @returns {number} Edge weight from source to target
|
|
227
|
-
*/
|
|
228
|
-
getEdgeWeight(source, target) {
|
|
229
|
-
const weight = this.#edgeWeights.get(source)?.get(target);
|
|
230
|
-
if (weight === undefined) {
|
|
231
|
-
throw new ReferenceError(
|
|
232
|
-
`Edge weight from ${q(source)} to ${q(target)} is not set`,
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
return weight;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
208
|
/**
|
|
239
209
|
* Adds an edge from the `source` node to `target` node.
|
|
240
210
|
*
|
|
@@ -245,17 +215,15 @@ export class GenericGraph {
|
|
|
245
215
|
*
|
|
246
216
|
* @param {T} source Source node
|
|
247
217
|
* @param {T} target Target node
|
|
248
|
-
* @param {number} weight Edge weight from source to target
|
|
249
218
|
* @returns {this} This graph instance
|
|
250
219
|
*/
|
|
251
|
-
addEdge(source, target
|
|
220
|
+
addEdge(source, target) {
|
|
252
221
|
this.addNode(source);
|
|
253
222
|
this.addNode(target);
|
|
254
223
|
const adjacentNodes = this.adjacent(source);
|
|
255
224
|
assert(adjacentNodes, `Source ${q(source)} should have adjacent nodes`);
|
|
256
225
|
|
|
257
226
|
adjacentNodes.add(target);
|
|
258
|
-
this.setEdgeWeight(source, target, weight);
|
|
259
227
|
return this;
|
|
260
228
|
}
|
|
261
229
|
|
|
@@ -284,42 +252,32 @@ export class GenericGraph {
|
|
|
284
252
|
}
|
|
285
253
|
|
|
286
254
|
/**
|
|
287
|
-
* Dijkstra's
|
|
288
|
-
*
|
|
255
|
+
* Dijkstra's single-source shortest path algorithm.
|
|
256
|
+
*
|
|
257
|
+
* Computes shortest paths from `source` to **all** reachable nodes.
|
|
258
|
+
*
|
|
259
|
+
* @template {GenericGraphNode} [T=string] The type of nodes in the graph
|
|
289
260
|
* @param {GenericGraph<T>} graph
|
|
290
261
|
* @param {T} source
|
|
291
|
-
* @param {T} target
|
|
292
262
|
* @returns {TraversalContext<T>}
|
|
293
263
|
*/
|
|
294
|
-
const dijkstra = (graph, source
|
|
264
|
+
const dijkstra = (graph, source) => {
|
|
295
265
|
const { nodes } = graph;
|
|
296
266
|
/** @type {TraversalContext<T>} */
|
|
297
267
|
const context = {
|
|
298
|
-
|
|
268
|
+
paths: new Map(),
|
|
299
269
|
predecessors: new Map(),
|
|
300
|
-
queue:
|
|
270
|
+
queue: nodes,
|
|
301
271
|
};
|
|
302
|
-
const { queue,
|
|
303
|
-
|
|
304
|
-
for (const node of nodes) {
|
|
305
|
-
distances.set(node, Infinity);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
assert(
|
|
309
|
-
distances.get(source) === Infinity,
|
|
310
|
-
`Source ${q(source)} is not in the graph`,
|
|
311
|
-
);
|
|
312
|
-
assert(
|
|
313
|
-
distances.get(target) === Infinity,
|
|
314
|
-
`Target ${q(target)} is not in the graph`,
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
distances.set(source, 0);
|
|
272
|
+
const { queue, paths } = context;
|
|
318
273
|
|
|
319
274
|
for (const node of nodes) {
|
|
320
275
|
queue.add(node);
|
|
321
276
|
}
|
|
322
277
|
|
|
278
|
+
assert(queue.has(source), `Source ${q(source)} is not in the graph`);
|
|
279
|
+
paths.set(source, []);
|
|
280
|
+
|
|
323
281
|
while (queue.size !== 0) {
|
|
324
282
|
const node = extractMin(context);
|
|
325
283
|
if (node === undefined) {
|
|
@@ -328,7 +286,7 @@ const dijkstra = (graph, source, target) => {
|
|
|
328
286
|
const adjacent = graph.adjacent(node);
|
|
329
287
|
if (adjacent) {
|
|
330
288
|
for (const edge of adjacent) {
|
|
331
|
-
relax(
|
|
289
|
+
relax(context, node, edge);
|
|
332
290
|
}
|
|
333
291
|
}
|
|
334
292
|
}
|
|
@@ -336,20 +294,32 @@ const dijkstra = (graph, source, target) => {
|
|
|
336
294
|
};
|
|
337
295
|
|
|
338
296
|
/**
|
|
339
|
-
* Returns a function which
|
|
340
|
-
*
|
|
297
|
+
* Returns a function which computes the shortest path from `source` to
|
|
298
|
+
* `target` in the given `graph`.
|
|
341
299
|
*
|
|
342
|
-
*
|
|
300
|
+
* Dijkstra's algorithm is a _single-source_ shortest path algorithm: one run
|
|
301
|
+
* produces shortest paths to every reachable node. The returned function
|
|
302
|
+
* caches the traversal context by source, so the first call for a given source
|
|
303
|
+
* pays O(V²) and every subsequent call with the same source is O(path length).
|
|
304
|
+
*
|
|
305
|
+
* @template {GenericGraphNode} [T=string]
|
|
343
306
|
* @param {GenericGraph<T>} graph Graph to use
|
|
344
307
|
*/
|
|
345
308
|
export const makeShortestPath = graph => {
|
|
309
|
+
/** @type {Map<T, TraversalContext<T>>} */
|
|
310
|
+
const contextCache = new Map();
|
|
311
|
+
|
|
346
312
|
/**
|
|
347
313
|
* @param {NoInfer<T>} source Source node
|
|
348
314
|
* @param {NoInfer<T>} target Target node
|
|
349
315
|
* @returns {[T, T, ...T[]]} Nodes from `source` to `target` inclusive (minimum of two nodes)
|
|
350
316
|
*/
|
|
351
317
|
const shortestPath = (source, target) => {
|
|
352
|
-
|
|
318
|
+
let context = contextCache.get(source);
|
|
319
|
+
if (!context) {
|
|
320
|
+
context = dijkstra(graph, source);
|
|
321
|
+
contextCache.set(source, context);
|
|
322
|
+
}
|
|
353
323
|
return getPath(context, source, target);
|
|
354
324
|
};
|
|
355
325
|
return shortestPath;
|
package/src/import-hook.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-hook.d.ts","sourceRoot":"","sources":["import-hook.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"import-hook.d.ts","sourceRoot":"","sources":["import-hook.js"],"names":[],"mappings":"AAquBA;;;;;;;GAOG;AACH,mDALW,aAAa,gBACb,aAAa,kKACb,6BAA6B,GAC3B,kBAAkB,CAqM9B;AA9tBM,oGALJ;IAAqC,OAAO;IACN,oBAAoB;IACnC,oBAAoB,EAAnC,MAAM;CACd,GAAU,oBAAoB,GAAC,SAAS,CA8B1C;AA0UM,gDALI,MAAM,GAAC,UAAU,gBACjB,aAAa,wMACb,0BAA0B,GACxB,eAAe,CA6K3B;mCAtrBS,YAAY;mCAAZ,YAAY;mDAAZ,YAAY;wCAAZ,YAAY;0CAAZ,YAAY;4BAAZ,YAAY;gCAAZ,YAAY;gDAAZ,YAAY;qCAAZ,YAAY"}
|
package/src/import-hook.js
CHANGED
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
* CompartmentModuleConfiguration,
|
|
42
42
|
* LogOptions,
|
|
43
43
|
* CanonicalName,
|
|
44
|
-
* LocalModuleSource
|
|
44
|
+
* LocalModuleSource,
|
|
45
|
+
* ModuleSourceHook,
|
|
45
46
|
* } from './types.js'
|
|
46
47
|
*/
|
|
47
48
|
|
|
@@ -262,7 +263,7 @@ const nominateCandidates = (moduleSpecifier, searchSuffixes) => {
|
|
|
262
263
|
*
|
|
263
264
|
* Preprocesses the fields for the hook.
|
|
264
265
|
*
|
|
265
|
-
* @param {
|
|
266
|
+
* @param {ModuleSourceHook | undefined} moduleSourceHook Hook function
|
|
266
267
|
* @param {LocalModuleSource} moduleSource Original `LocalModuleSource` object
|
|
267
268
|
* @param {CanonicalName} canonicalName Canonical name of the compartment/package
|
|
268
269
|
* @param {LogOptions} options Options
|
|
@@ -485,7 +486,7 @@ function* chooseModuleDescriptor(
|
|
|
485
486
|
parser,
|
|
486
487
|
bytes: transformedBytes,
|
|
487
488
|
record: concreteRecord,
|
|
488
|
-
sha512,
|
|
489
|
+
...(sha512 !== undefined && { sha512 }),
|
|
489
490
|
};
|
|
490
491
|
|
|
491
492
|
packageSources[candidateSpecifier] = localModuleSource;
|
package/src/infer-exports.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export function inferExportsEntries({ main, module, exports }: PackageDescriptor, conditions: Set<string>, types: LanguageForExtension): Generator<string[], void, any>;
|
|
1
|
+
export function inferExportsEntries({ main, module, exports }: PackageDescriptor, conditions: Set<string>, types: LanguageForExtension): Generator<string[] | [string, string | null], void, any>;
|
|
2
2
|
export function inferExports(descriptor: PackageDescriptor, conditions: Set<string>, types: LanguageForExtension): Record<string, string>;
|
|
3
|
-
export function
|
|
3
|
+
export function inferExportsAliasesAndPatterns(descriptor: PackageDescriptor, externalAliases: Node["externalAliases"], internalAliases: Node["internalAliases"], patterns: PatternDescriptor[], conditions: Set<string>, types: Record<string, string>, log: LogFn): void;
|
|
4
4
|
import type { PackageDescriptor } from './types.js';
|
|
5
5
|
import type { LanguageForExtension } from './types.js';
|
|
6
6
|
import type { Node } from './types/node-modules.js';
|
|
7
|
+
import type { PatternDescriptor } from './types/pattern-replacement.js';
|
|
8
|
+
import type { LogFn } from './types/external.js';
|
|
7
9
|
//# sourceMappingURL=infer-exports.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infer-exports.d.ts","sourceRoot":"","sources":["infer-exports.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"infer-exports.d.ts","sourceRoot":"","sources":["infer-exports.js"],"names":[],"mappings":"AAyLO,+DAPI,iBAAiB,cACjB,GAAG,CAAC,MAAM,CAAC,SAEX,oBAAoB,4DA2B9B;AAkBM,yCAPI,iBAAiB,cACjB,GAAG,CAAC,MAAM,CAAC,SAEX,oBAAoB,GAElB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAG8B;AAyD1D,2DARI,iBAAiB,mBACjB,IAAI,CAAC,iBAAiB,CAAC,mBACvB,IAAI,CAAC,iBAAiB,CAAC,YACvB,iBAAiB,EAAE,cACnB,GAAG,CAAC,MAAM,CAAC,SACX,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OACtB,KAAK,QAsFf;uCArWyD,YAAY;0CAAZ,YAAY;0BAE7B,yBAAyB;uCAC9B,gCAAgC;2BAF5C,qBAAqB"}
|