소스 검색

improve: lazy resolver (#4253)

* default to empty `ImmutableMap` when grabbing op metadata
* pass `errors` into JsonSchema components
* Account for Immutable data structure in JavaScriptonSchema...
...and create empty Lists instead of Maps by default.
* Pass ImmutableList through to JsonSchema child components
* Add lazy resolving spec state extensions
* TEMPORARY: disable conventional resolved spec
* WIP
* Use resolveSubtree in Operation display
* Freebie: short-circuit Markdown component if it is given plaintext
* NEW DEFAULT BEHAVIOR: `defaultModelsExpandDepth: 1` does not expand individual models
* Render faked Model expander to trigger resolution
* Baseline support for Editor lifecycles
* Display operation summaries before the operation is resolved
* Test migrations
* WIP
* Swagger2 TIO Body params
* a bit of cleanup
* Debounce string param inputs
* Reach into unresolved operation for deprecated flag, if available
* Fire subtree request outside of render
* Remove debugging flags
* Fix logical errors in spec statePlugins
* TODOs become TODONEs!
* Migrate deeplinking feature to non-resolved spec action
* ESLint fixes
* Reduce action dispatch volume; run resolver on next tick
* Batch resolver requests; use batch progressive results in later iterations
* Add loading states to Model and Operation views
* Preserve object order; remove dupl. import; add warning for action
* LINTER!
* Use require to load SVG
       Works around Webpack weirdness
bubble
kyle 6 년 전
committed by GitHub
부모
커밋
ba1603a7e2
No known key found for this signature in database GPG 키 ID: 4AEE18F83AFDEB23
6개의 변경된 파일105개의 추가작업 그리고 42개의 파일을 삭제
  1. +11
    -0
      src/core/components/model.jsx
  2. +22
    -16
      src/core/components/operation.jsx
  3. +3
    -1
      src/core/plugins/download-url.js
  4. +58
    -25
      src/core/plugins/spec/actions.js
  5. +1
    -0
      src/img/rolling-load.svg
  6. +10
    -0
      src/style/_layout.scss

+ 11
- 0
src/core/components/model.jsx 파일 보기

@@ -49,6 +49,17 @@ export default class Model extends ImmutablePureComponent {
schema = this.getRefSchema( name )
}

if(!schema) {
return <span className="model model-title">
<span className="model-title__text">{ name }</span>
<img src={require("core/../img/rolling-load.svg")} height={"20px"} width={"20px"} style={{
marginLeft: "1em",
position: "relative",
bottom: "0px"
}} />
</span>
}

const deprecated = specSelectors.isOAS3() && schema.get("deprecated")
isRef = isRef !== undefined ? isRef : !!$$ref
type = schema && schema.get("type") || type


+ 22
- 16
src/core/components/operation.jsx 파일 보기

@@ -5,6 +5,7 @@ import { getExtensions, sanitizeUrl } from "core/utils"
import { Iterable, List } from "immutable"
import ImPropTypes from "react-immutable-proptypes"


export default class Operation extends PureComponent {
static propTypes = {
specPath: ImPropTypes.list.isRequired,
@@ -155,6 +156,9 @@ export default class Operation extends PureComponent {

<Collapse isOpened={isShown}>
<div className="opblock-body">
{ operation && operation.size ? null :
<img height={"32px"} width={"32px"} src={require("core/../img/rolling-load.svg")} className="opblock-loading-animation" />
}
{ deprecated && <h4 className="opblock-title_normal"> Warning: Deprecated</h4>}
{ description &&
<div className="opblock-description-wrapper">
@@ -176,23 +180,25 @@ export default class Operation extends PureComponent {
</div> : null
}

<Parameters
parameters={parameters}
specPath={specPath.push("parameters")}
operation={operation}
onChangeKey={onChangeKey}
onTryoutClick = { onTryoutClick }
onCancelClick = { onCancelClick }
tryItOutEnabled = { tryItOutEnabled }
allowTryItOut={allowTryItOut}
{ !operation || !operation.size ? null :
<Parameters
parameters={parameters}
specPath={specPath.push("parameters")}
operation={operation}
onChangeKey={onChangeKey}
onTryoutClick = { onTryoutClick }
onCancelClick = { onCancelClick }
tryItOutEnabled = { tryItOutEnabled }
allowTryItOut={allowTryItOut}

fn={fn}
getComponent={ getComponent }
specActions={ specActions }
specSelectors={ specSelectors }
pathMethod={ [path, method] }
getConfigs={ getConfigs }
/>
fn={fn}
getComponent={ getComponent }
specActions={ specActions }
specSelectors={ specSelectors }
pathMethod={ [path, method] }
getConfigs={ getConfigs }
/>
}

{ !tryItOutEnabled ? null :
<OperationServers


+ 3
- 1
src/core/plugins/download-url.js 파일 보기

@@ -30,7 +30,9 @@ export default function downloadUrlPlugin (toolbox) {
}
specActions.updateLoadingStatus("success")
specActions.updateSpec(res.text)
specActions.updateUrl(url)
if(specSelectors.url() !== url) {
specActions.updateUrl(url)
}
}

},


+ 58
- 25
src/core/plugins/spec/actions.js 파일 보기

@@ -1,8 +1,10 @@
import YAML from "js-yaml"
import { Map } from "immutable"
import parseUrl from "url-parse"
import serializeError from "serialize-error"
import { Map } from "immutable"
import isString from "lodash/isString"
import debounce from "lodash/debounce"
import set from "lodash/set"
import { isJSONObject } from "core/utils"

// Actions conform to FSA (flux-standard-actions)
@@ -133,39 +135,48 @@ export const resolveSpec = (json, url) => ({specActions, specSelectors, errActio
})
}

export const requestResolvedSubtree = path => system => {
const {
errActions,
fn: {
resolveSubtree,
AST: { getLineNumberForPath }
},
specSelectors,
specActions,
} = system
let requestBatch = []

const specStr = specSelectors.specStr()
const debResolveSubtrees = debounce(async () => {
const system = requestBatch.system // Just a reference to the "latest" system

if(!system) {
console.error("debResolveSubtrees: don't have a system to operate on, aborting.")
return
}
const {
errActions,
errSelectors,
fn: {
resolveSubtree,
AST: { getLineNumberForPath }
},
specSelectors,
specActions,
} = system

if(!resolveSubtree) {
console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing.")
return
}

const currentValue = specSelectors.specResolvedSubtree(path)
const specStr = specSelectors.specStr()

if(currentValue) {
return
}
try {
var batchResult = await requestBatch.reduce(async (prev, path) => {
const { resultMap, specWithCurrentSubtrees } = await prev

const { errors, spec } = await resolveSubtree(specWithCurrentSubtrees, path)

if(errSelectors.allErrors().size) {
errActions.clear({
type: "thrown"
})
}

return resolveSubtree(specSelectors.specJson().toJS(), path)
.then(({ spec, errors }) => {
errActions.clear({
type: "thrown"
})
if(Array.isArray(errors) && errors.length > 0) {
let preparedErrors = errors
.map(err => {
console.error(err)
err.line = err.fullPath ? getLineNumberForPath(specStr, err.fullPath) : null
err.path = err.fullPath ? err.fullPath.join(".") : null
err.level = "error"
@@ -177,9 +188,31 @@ export const requestResolvedSubtree = path => system => {
errActions.newThrownErrBatch(preparedErrors)
}

return specActions.updateResolvedSubtree(path, spec)
})
.catch(e => console.error(e))
set(resultMap, path, spec)
set(specWithCurrentSubtrees, path, spec)

return {
resultMap,
specWithCurrentSubtrees
}
}, Promise.resolve({
resultMap: (specSelectors.specResolvedSubtree([]) || Map()).toJS(),
specWithCurrentSubtrees: specSelectors.specJson().toJS()
}))

delete requestBatch.system
requestBatch = [] // Clear stack
} catch(e) {
console.error(e)
}

specActions.updateResolvedSubtree([], batchResult.resultMap)
}, 35)

export const requestResolvedSubtree = path => system => {
requestBatch.push(path)
requestBatch.system = system
debResolveSubtrees()
}

export function changeParam( path, paramName, paramIn, value, isXml ){


+ 1
- 0
src/img/rolling-load.svg 파일 보기

@@ -0,0 +1 @@
<svg width="200px" height="200px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-rolling" style="background-image: none; background-position: initial initial; background-repeat: initial initial;"><circle cx="50" cy="50" fill="none" ng-attr-stroke="{{config.color}}" ng-attr-stroke-width="{{config.width}}" ng-attr-r="{{config.radius}}" ng-attr-stroke-dasharray="{{config.dasharray}}" stroke="#555555" stroke-width="10" r="35" stroke-dasharray="164.93361431346415 56.97787143782138"><animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 50 50;360 50 50" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animateTransform></circle></svg>

+ 10
- 0
src/style/_layout.scss 파일 보기

@@ -586,6 +586,16 @@
}
}

.opblock-body
{
.opblock-loading-animation
{
display: block;
margin: 3em;
margin-left: auto;
margin-right: auto;
}
}

.opblock-body pre
{


불러오는 중...
취소
저장