@abi-software/simulationvuer 2.0.6 → 2.0.8
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/dist/simulationvuer.js +15930 -15965
- package/dist/simulationvuer.umd.cjs +55 -54
- package/dist/style.css +1 -1
- package/package.json +9 -8
- package/src/App.vue +112 -18
- package/src/components/SimulationVuer.vue +60 -43
- package/vuese-generator.js +78 -17
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<p class="default note" v-if="uuid">Additional parameters are available on oSPARC</p>
|
|
34
34
|
</div>
|
|
35
35
|
<div class="main-right" ref="output" v-show="isSimulationValid">
|
|
36
|
-
<PlotVuer v-for="(
|
|
36
|
+
<PlotVuer v-for="(_outputPlot, index) in simulationUiInfo.output.plots"
|
|
37
37
|
:key="`output-${index}`"
|
|
38
38
|
:metadata="plotMetadata(index)"
|
|
39
39
|
:data-source="{data: simulationResults[index]}"
|
|
@@ -82,7 +82,7 @@ export default {
|
|
|
82
82
|
},
|
|
83
83
|
props: {
|
|
84
84
|
/**
|
|
85
|
-
* The
|
|
85
|
+
* The URL to the API location.
|
|
86
86
|
*/
|
|
87
87
|
apiLocation: {
|
|
88
88
|
required: true,
|
|
@@ -93,7 +93,16 @@ export default {
|
|
|
93
93
|
* to a PMR file, if it is a string.
|
|
94
94
|
*/
|
|
95
95
|
id: {
|
|
96
|
-
required:
|
|
96
|
+
required: false,
|
|
97
|
+
default: 0,
|
|
98
|
+
},
|
|
99
|
+
/**
|
|
100
|
+
* A COMBINE archive that was passed directly.
|
|
101
|
+
*/
|
|
102
|
+
combineArchive: {
|
|
103
|
+
required: false,
|
|
104
|
+
type: Uint8Array,
|
|
105
|
+
default: undefined,
|
|
97
106
|
},
|
|
98
107
|
},
|
|
99
108
|
data: function() {
|
|
@@ -145,7 +154,7 @@ export default {
|
|
|
145
154
|
},
|
|
146
155
|
methods: {
|
|
147
156
|
/**
|
|
148
|
-
* @
|
|
157
|
+
* @public
|
|
149
158
|
* Generate the metadata associated with the plot which `index` is given.
|
|
150
159
|
* @arg `index`
|
|
151
160
|
*/
|
|
@@ -160,30 +169,7 @@ export default {
|
|
|
160
169
|
};
|
|
161
170
|
},
|
|
162
171
|
/**
|
|
163
|
-
* @
|
|
164
|
-
* Download the PMR file associated with the given `url`.
|
|
165
|
-
* @arg `url`
|
|
166
|
-
*/
|
|
167
|
-
downloadPmrFile(url) {
|
|
168
|
-
return new Promise((resolve, reject) => {
|
|
169
|
-
const xmlhttp = new XMLHttpRequest();
|
|
170
|
-
|
|
171
|
-
xmlhttp.open("POST", this.apiLocation + "/pmr_file");
|
|
172
|
-
xmlhttp.setRequestHeader("Content-type", "application/json");
|
|
173
|
-
xmlhttp.onreadystatechange = () => {
|
|
174
|
-
if (xmlhttp.readyState === 4) {
|
|
175
|
-
if (xmlhttp.status === 200) {
|
|
176
|
-
resolve(Uint8Array.from(atob(xmlhttp.response), (c) => c.charCodeAt(0)));
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
reject();
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
xmlhttp.send(JSON.stringify({path: url.replace(PMR_URL, "")}));
|
|
183
|
-
});
|
|
184
|
-
},
|
|
185
|
-
/**
|
|
186
|
-
* @vuese
|
|
172
|
+
* @public
|
|
187
173
|
* Manage the file associated with the given `url` and `fileContents`.
|
|
188
174
|
* @arg `url`
|
|
189
175
|
* @arg `fileContents`
|
|
@@ -207,7 +193,7 @@ export default {
|
|
|
207
193
|
return file;
|
|
208
194
|
},
|
|
209
195
|
/**
|
|
210
|
-
* @
|
|
196
|
+
* @public
|
|
211
197
|
* Run a PMR-based COMBINE archive using libOpenCOR.
|
|
212
198
|
*/
|
|
213
199
|
runSimulation() {
|
|
@@ -267,7 +253,7 @@ export default {
|
|
|
267
253
|
this.showUserMessage = false;
|
|
268
254
|
},
|
|
269
255
|
/**
|
|
270
|
-
* @
|
|
256
|
+
* @public
|
|
271
257
|
* Build the simulation UI using `simulationUiInfo`, a JSON object that describes the contents of the simulation UI.
|
|
272
258
|
* @arg `simulationUiInfo`
|
|
273
259
|
*/
|
|
@@ -303,7 +289,8 @@ export default {
|
|
|
303
289
|
this.opencorBasedSimulation = this.solver.name === OPENCOR_SOLVER_NAME;
|
|
304
290
|
}
|
|
305
291
|
|
|
306
|
-
// Run the model if we are dealing with a PMR-based COMBINE archive
|
|
292
|
+
// Run the model if we are dealing with a PMR-based COMBINE archive or a
|
|
293
|
+
// COMBINE archive that was passed directly.
|
|
307
294
|
|
|
308
295
|
if (this.libopencor !== undefined) {
|
|
309
296
|
this.userMessage = "Running the model...";
|
|
@@ -371,7 +358,7 @@ export default {
|
|
|
371
358
|
});
|
|
372
359
|
},
|
|
373
360
|
/**
|
|
374
|
-
* @
|
|
361
|
+
* @public
|
|
375
362
|
* Run the simulation-based dataset directly on oSPARC. Not all simulation-based datasets can be run directly on
|
|
376
363
|
* oSPARC, but for those that can the simulation UI shows a `Run on oSPARC` button which, when clicked, calls this
|
|
377
364
|
* method.
|
|
@@ -380,7 +367,7 @@ export default {
|
|
|
380
367
|
window.open(`https://osparc.io/study/${this.uuid}`, "_blank");
|
|
381
368
|
},
|
|
382
369
|
/**
|
|
383
|
-
* @
|
|
370
|
+
* @public
|
|
384
371
|
* View the simulation-based dataset on the SPARC portal. The simulation UI has a `View Dataset` button which, when
|
|
385
372
|
* clicked, calls this method.
|
|
386
373
|
*/
|
|
@@ -388,7 +375,7 @@ export default {
|
|
|
388
375
|
window.open(`https://sparc.science/datasets/${this.id}?type=dataset`, "_blank");
|
|
389
376
|
},
|
|
390
377
|
/**
|
|
391
|
-
* @
|
|
378
|
+
* @public
|
|
392
379
|
* View the simulation-based dataset on PMR. The simulation UI has a `View Workspace` button which, when clicked,
|
|
393
380
|
* calls this method.
|
|
394
381
|
*/
|
|
@@ -398,7 +385,7 @@ export default {
|
|
|
398
385
|
window.open(url.substring(0, url.lastIndexOf("/")), "_blank");
|
|
399
386
|
},
|
|
400
387
|
/**
|
|
401
|
-
* @
|
|
388
|
+
* @public
|
|
402
389
|
* Data needed to set a model's parameters.
|
|
403
390
|
*/
|
|
404
391
|
parametersData() {
|
|
@@ -411,7 +398,7 @@ export default {
|
|
|
411
398
|
return res;
|
|
412
399
|
},
|
|
413
400
|
/**
|
|
414
|
-
* @
|
|
401
|
+
* @public
|
|
415
402
|
* Data needed to specify the model output.
|
|
416
403
|
*/
|
|
417
404
|
outputData() {
|
|
@@ -428,7 +415,7 @@ export default {
|
|
|
428
415
|
return this.output;
|
|
429
416
|
},
|
|
430
417
|
/**
|
|
431
|
-
* @
|
|
418
|
+
* @public
|
|
432
419
|
* Create the `request` that is going to be used by `startSimulation` to ask oSPARC to start the simulation.
|
|
433
420
|
*/
|
|
434
421
|
retrieveRequest() {
|
|
@@ -466,7 +453,7 @@ export default {
|
|
|
466
453
|
return request;
|
|
467
454
|
},
|
|
468
455
|
/**
|
|
469
|
-
* @
|
|
456
|
+
* @public
|
|
470
457
|
* Process the simulation results retrieved by `checkSimulation`. The simulation results are post-processed, if
|
|
471
458
|
* needed, and then readied for use by `PlotVuer`.
|
|
472
459
|
* @arg `results`
|
|
@@ -521,7 +508,7 @@ export default {
|
|
|
521
508
|
});
|
|
522
509
|
},
|
|
523
510
|
/**
|
|
524
|
-
* @
|
|
511
|
+
* @public
|
|
525
512
|
* Show an HTTP issue using the given `xmlhttp`.
|
|
526
513
|
* @arg `xmlhttp`
|
|
527
514
|
*/
|
|
@@ -531,7 +518,7 @@ export default {
|
|
|
531
518
|
this.errorMessage = xmlhttp.statusText.toLowerCase() + " (<a href='https://httpstatuses.com/" + xmlhttp.status + "/' target='_blank'>" + xmlhttp.status + "</a>)";
|
|
532
519
|
},
|
|
533
520
|
/**
|
|
534
|
-
* @
|
|
521
|
+
* @public
|
|
535
522
|
* Check the progress of the simulation using the given `data`, a JSON object that contains the simulation job ID,
|
|
536
523
|
* as well as the solver name and version. This method is first called by `startSimulation` and then every second by
|
|
537
524
|
* itself until the simulation is finished.
|
|
@@ -580,7 +567,7 @@ export default {
|
|
|
580
567
|
xmlhttp.send(JSON.stringify(data));
|
|
581
568
|
},
|
|
582
569
|
/**
|
|
583
|
-
* @
|
|
570
|
+
* @public
|
|
584
571
|
* Start the simulation associated with the simulation-based dataset. The simulation UI has a `Run Simulation`
|
|
585
572
|
* button which, when clicked, calls this method.
|
|
586
573
|
*/
|
|
@@ -650,8 +637,8 @@ export default {
|
|
|
650
637
|
this.userMessage = "Retrieving COMBINE archive from PMR...";
|
|
651
638
|
this.showUserMessage = true;
|
|
652
639
|
|
|
653
|
-
// Retrieve the
|
|
654
|
-
// then build the simulation UI.
|
|
640
|
+
// Retrieve the COMBINE archive, extract the simulation UI JSON file from
|
|
641
|
+
// it and then build the simulation UI.
|
|
655
642
|
|
|
656
643
|
this.$nextTick(() => {
|
|
657
644
|
const xmlhttp = new XMLHttpRequest();
|
|
@@ -685,6 +672,36 @@ export default {
|
|
|
685
672
|
};
|
|
686
673
|
xmlhttp.send(JSON.stringify({path: this.id}));
|
|
687
674
|
});
|
|
675
|
+
} else if (this.combineArchive !== undefined) {
|
|
676
|
+
// Extract the simulation UI JSON file from the COMBINE archive and build
|
|
677
|
+
// the simulation UI.
|
|
678
|
+
|
|
679
|
+
this.userMessage = "Retrieving COMBINE archive...";
|
|
680
|
+
this.showUserMessage = true;
|
|
681
|
+
|
|
682
|
+
this.$nextTick(() => {
|
|
683
|
+
libOpenCOR().then((libopencor) => {
|
|
684
|
+
this.libopencor = markRaw(libopencor);
|
|
685
|
+
this.libopencorSet = true;
|
|
686
|
+
this.fileManager = markRaw(this.libopencor.FileManager.instance());
|
|
687
|
+
|
|
688
|
+
const fileContents = this.combineArchive;
|
|
689
|
+
const file = this.manageFile(PMR_URL + this.id, fileContents);
|
|
690
|
+
|
|
691
|
+
if (file.type().value !== libopencor.File.Type.COMBINE_ARCHIVE.value) {
|
|
692
|
+
this.showUserMessage = false;
|
|
693
|
+
} else {
|
|
694
|
+
const decoder = new TextDecoder();
|
|
695
|
+
const simulationUiInfo = JSON.parse(decoder.decode(file.childFile("simulation.json").contents()));
|
|
696
|
+
|
|
697
|
+
this.showUserMessage = false;
|
|
698
|
+
|
|
699
|
+
this.$nextTick(() => {
|
|
700
|
+
this.buildSimulationUi(simulationUiInfo);
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
});
|
|
688
705
|
}
|
|
689
706
|
},
|
|
690
707
|
mounted: function() {
|
package/vuese-generator.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import fs from 'fs'
|
|
9
9
|
import path from 'path'
|
|
10
10
|
import chokidar from 'chokidar'
|
|
11
|
-
import {
|
|
11
|
+
import { parseSource } from 'vue-docgen-api'
|
|
12
12
|
import { Render } from '@vuese/markdown-render'
|
|
13
13
|
|
|
14
14
|
const watchMode = process.argv.find((argv) => argv === 'watch')
|
|
@@ -22,30 +22,91 @@ function generateMarkdown(file) {
|
|
|
22
22
|
const fileContent = fs.readFileSync(fileWithPath, 'utf-8')
|
|
23
23
|
|
|
24
24
|
try {
|
|
25
|
-
const parserResult = parser(fileContent)
|
|
26
|
-
parserResult
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
// const parserResult = parser(fileContent)
|
|
26
|
+
const parserResult = parseSource(fileContent, fileWithPath)
|
|
27
|
+
parserResult.then((result) => {
|
|
28
|
+
const {
|
|
29
|
+
displayName: name,
|
|
30
|
+
description: desc,
|
|
31
|
+
props,
|
|
32
|
+
events,
|
|
33
|
+
methods
|
|
34
|
+
} = result
|
|
35
|
+
|
|
36
|
+
// transform props to vuese styles
|
|
37
|
+
const parseResult = {
|
|
38
|
+
name: name,
|
|
39
|
+
componentDesc: {
|
|
40
|
+
default: [desc]
|
|
41
|
+
},
|
|
42
|
+
props: transformData(props),
|
|
43
|
+
events: transformData(events),
|
|
44
|
+
methods: transformData(methods),
|
|
45
|
+
}
|
|
46
|
+
parseResult.name = 'SimulationVuer' // Because there has another name prop in component
|
|
47
|
+
const r = new Render(parseResult)
|
|
48
|
+
const renderResult = r.render()
|
|
49
|
+
const markdownResult = r.renderMarkdown()
|
|
50
|
+
const markdownContent = markdownResult.content
|
|
51
|
+
const componentName = path.basename(fileWithPath, '.vue')
|
|
36
52
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
console.error(`Error writing markdown file for ${componentName}`, err)
|
|
40
|
-
} else {
|
|
41
|
-
console.log(`Markdown file for ${componentName} is generated!`)
|
|
53
|
+
if (!fs.existsSync(outputDir)) {
|
|
54
|
+
fs.mkdirSync(outputDir)
|
|
42
55
|
}
|
|
56
|
+
|
|
57
|
+
fs.writeFile(`${outputDir}/${componentName}.md`, markdownContent, (err) => {
|
|
58
|
+
if (err) {
|
|
59
|
+
console.error(`Error writing markdown file for ${componentName}`, err)
|
|
60
|
+
} else {
|
|
61
|
+
console.log(`Markdown file for ${componentName} is generated!`)
|
|
62
|
+
}
|
|
63
|
+
})
|
|
43
64
|
})
|
|
44
65
|
} catch(e) {
|
|
45
66
|
console.error(e)
|
|
46
67
|
}
|
|
47
68
|
}
|
|
48
69
|
|
|
70
|
+
function transformData(data = []) {
|
|
71
|
+
data.forEach((prop) => {
|
|
72
|
+
prop.name = prop.name
|
|
73
|
+
|
|
74
|
+
if (prop.description) {
|
|
75
|
+
prop.describe = [prop.description.replaceAll('\n', ' ')]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (prop.type) {
|
|
79
|
+
prop.type = prop.type.name
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (prop.defaultValue) {
|
|
83
|
+
prop.default = prop.defaultValue.value.replaceAll('\n', ' ')
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// events
|
|
87
|
+
if (prop.properties) {
|
|
88
|
+
prop.argumentsDesc = []
|
|
89
|
+
prop.properties.forEach((param) => {
|
|
90
|
+
const argName = param.name || param.description
|
|
91
|
+
prop.argumentsDesc.push(argName)
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// methods
|
|
96
|
+
if (prop.params) {
|
|
97
|
+
prop.argumentsDesc = []
|
|
98
|
+
prop.params.forEach((param) => {
|
|
99
|
+
const argName = param.description || param.name
|
|
100
|
+
prop.argumentsDesc.push(argName)
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
if (!data.length) {
|
|
105
|
+
return null
|
|
106
|
+
}
|
|
107
|
+
return data
|
|
108
|
+
}
|
|
109
|
+
|
|
49
110
|
// To generate markdown files - one time
|
|
50
111
|
components.forEach((component) => {
|
|
51
112
|
console.log(`Write markdown file for ${component} on first load.`)
|