Skip to content

Commit

Permalink
always reuse AJV instance from store
Browse files Browse the repository at this point in the history
  • Loading branch information
DBosley committed Aug 19, 2020
1 parent 15348c0 commit 57af381
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 37 deletions.
5 changes: 3 additions & 2 deletions packages/angular-material/src/other/label.renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import {
OwnPropsOfRenderer,
RankedTester,
rankWith,
uiTypeIs
uiTypeIs,
getOrCreateAjv
} from '@jsonforms/core';
import { Subscription } from 'rxjs';

Expand All @@ -46,7 +47,7 @@ const mapStateToProps = (
const visible =
ownProps.visible !== undefined
? ownProps.visible
: isVisible(ownProps.uischema, getData(state));
: isVisible(ownProps.uischema, getData(state), undefined, getOrCreateAjv(state));

return {
visible
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/reducers/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ export const coreReducer = (
export const extractData = (state: JsonFormsCore) => get(state, 'data');
export const extractSchema = (state: JsonFormsCore) => get(state, 'schema');
export const extractUiSchema = (state: JsonFormsCore) => get(state, 'uischema');
export const extractOrCreateAjv = (state: JsonFormsCore) => getOrCreateAjv(state);

export const errorsAt = (
instancePath: string,
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
extractRefParserOptions,
extractSchema,
extractUiSchema,
extractOrCreateAjv,
subErrorsAt,
ValidationMode
} from './core';
Expand Down Expand Up @@ -63,6 +64,7 @@ import RefParser from 'json-schema-ref-parser';
import { cellReducer } from './cells';
import { configReducer } from './config';
import get from 'lodash/get';
import { Ajv } from 'ajv';

export {
rendererReducer,
Expand Down Expand Up @@ -98,6 +100,9 @@ export const getUiSchema = (state: JsonFormsState): UISchemaElement =>
extractUiSchema(get(state, 'jsonforms.core'));
export const getRefParserOptions = (state: JsonFormsState): RefParser.Options =>
extractRefParserOptions(get(state, 'jsonforms.core'));
export const getOrCreateAjv = (
state: JsonFormsState
): Ajv => extractOrCreateAjv(get(state, 'jsonforms.core'));
export const getDefaultData = (
state: JsonFormsState
): JsonFormsDefaultDataRegistryEntry[] =>
Expand All @@ -108,7 +113,6 @@ export const getRenderers = (
export const getCells = (
state: JsonFormsState
): JsonFormsCellRendererRegistryEntry[] => get(state, 'jsonforms.cells');

/**
* Finds a registered UI schema to use, if any.
* @param schema the JSON schema describing the data to be rendered
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/util/cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*/
import isEmpty from 'lodash/isEmpty';
import union from 'lodash/union';
import { getConfig, getData, getErrorAt, getSchema } from '../reducers';
import { getConfig, getData, getErrorAt, getSchema, getOrCreateAjv } from '../reducers';
import {
formatErrorMessage,
isEnabled,
Expand Down Expand Up @@ -107,12 +107,12 @@ export const mapStateToCellProps = (
const visible =
ownProps.visible !== undefined
? ownProps.visible
: isVisible(uischema, rootData);
: isVisible(uischema, rootData, undefined, getOrCreateAjv(state));
const readOnly = state.jsonforms.readOnly;
const enabled =
!readOnly && (ownProps.enabled !== undefined
? ownProps.enabled
: isEnabled(uischema, rootData));
: isEnabled(uischema, rootData, undefined, getOrCreateAjv(state)));
const errors = formatErrorMessage(
union(getErrorAt(path, schema)(state).map(error => error.message))
);
Expand Down
10 changes: 6 additions & 4 deletions packages/core/src/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import {
toDataPathSegments
} from './path';
import { isEnabled, isVisible } from './runtime';
import { Ajv } from 'ajv';
import { createAjv } from './validator';

export { createCleanLabel, createLabelDescriptionFrom } from './label';

Expand Down Expand Up @@ -132,11 +134,11 @@ export { composePaths, composeWithUi, Paths, toDataPath };

// Runtime --
const Runtime = {
isEnabled(uischema: UISchemaElement, data: any): boolean {
return isEnabled(uischema, data);
isEnabled(uischema: UISchemaElement, data: any, ajv: Ajv = createAjv()): boolean {
return isEnabled(uischema, data,undefined, ajv);
},
isVisible(uischema: UISchemaElement, data: any): boolean {
return isVisible(uischema, data);
isVisible(uischema: UISchemaElement, data: any, ajv: Ajv = createAjv()): boolean {
return isVisible(uischema, data, undefined, ajv);
}
};
export { isEnabled, isVisible, Runtime, deriveTypes, hasType };
Expand Down
25 changes: 17 additions & 8 deletions packages/core/src/util/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ import {
getSchema,
getSubErrorsAt,
getUiSchema,
UISchemaTester
UISchemaTester,
getOrCreateAjv
} from '../reducers';
import { RankedTester } from '../testers';
import { JsonSchema } from '../models/jsonSchema';
Expand All @@ -58,7 +59,7 @@ import {
resolveSubSchemas
} from '../util';
import { update, CoreActions } from '../actions';
import { ErrorObject } from 'ajv';
import { ErrorObject, Ajv } from 'ajv';
import { JsonFormsState } from '../store';
import { AnyAction, Dispatch } from 'redux';
import { JsonFormsRendererRegistryEntry } from '../reducers/renderers';
Expand Down Expand Up @@ -274,6 +275,12 @@ export interface StatePropsOfRenderer {
*/

cells?: JsonFormsCellRendererRegistryEntry[];

/**
* AJV instance from core state.
*/

ajv?: Ajv;
}

/**
Expand Down Expand Up @@ -395,12 +402,12 @@ export const mapStateToControlProps = (
const path = composeWithUi(uischema, ownProps.path);
const visible: boolean =
ownProps.visible === undefined || hasShowRule(uischema)
? isVisible(uischema, rootData, ownProps.path)
? isVisible(uischema, rootData, ownProps.path, getOrCreateAjv(state))
: ownProps.visible;
const readOnly = state.jsonforms.readOnly;
const enabled: boolean =
!readOnly && (ownProps.enabled === undefined || hasEnableRule(uischema)
? isEnabled(uischema, rootData, ownProps.path)
? isEnabled(uischema, rootData, ownProps.path, getOrCreateAjv(state) )
: ownProps.enabled);
const controlElement = uischema as ControlElement;
const id = ownProps.id;
Expand Down Expand Up @@ -702,15 +709,16 @@ export const mapStateToLayoutProps = (
ownProps: OwnPropsOfLayout
): LayoutProps => {
const rootData = getData(state);
const ajv = getOrCreateAjv(state);
const { uischema } = ownProps;
const visible: boolean =
ownProps.visible === undefined || hasShowRule(uischema)
? isVisible(ownProps.uischema, rootData, ownProps.path)
? isVisible(ownProps.uischema, rootData, ownProps.path, getOrCreateAjv(state))
: ownProps.visible;
const readOnly = state.jsonforms.readOnly;
const enabled: boolean =
!readOnly && (ownProps.enabled === undefined || hasEnableRule(uischema)
? isEnabled(ownProps.uischema, rootData, ownProps.path)
? isEnabled(ownProps.uischema, rootData, ownProps.path, getOrCreateAjv(state))
: ownProps.enabled);

const data = Resolve.data(rootData, ownProps.path);
Expand All @@ -725,7 +733,8 @@ export const mapStateToLayoutProps = (
data,
uischema: ownProps.uischema,
schema: ownProps.schema,
direction: ownProps.direction || layoutDefaultProps.direction
direction: ownProps.direction || layoutDefaultProps.direction,
ajv
};
};

Expand Down Expand Up @@ -800,7 +809,7 @@ const mapStateToCombinatorRendererProps = (
);
const visible: boolean =
ownProps.visible === undefined || hasShowRule(uischema)
? isVisible(uischema, getData(state), ownProps.path)
? isVisible(uischema, getData(state), ownProps.path, getOrCreateAjv(state))
: ownProps.visible;
const id = ownProps.id;

Expand Down
35 changes: 20 additions & 15 deletions packages/core/src/util/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ import {
import { resolveData } from './resolvers';
import { composeWithUi } from './path';
import { createAjv } from './validator';

const ajv = createAjv();
import { Ajv } from 'ajv';

const isOrCondition = (condition: Condition): condition is OrCondition =>
condition.type === 'OR';
Expand All @@ -59,16 +58,17 @@ const getConditionScope = (condition: Scopable, path: string): string => {
const evaluateCondition = (
data: any,
condition: Condition,
path: string
path: string,
ajv: Ajv
): boolean => {
if (isAndCondition(condition)) {
return condition.conditions.reduce(
(acc, cur) => acc && evaluateCondition(data, cur, path),
(acc, cur) => acc && evaluateCondition(data, cur, path, ajv),
true
);
} else if (isOrCondition(condition)) {
return condition.conditions.reduce(
(acc, cur) => acc || evaluateCondition(data, cur, path),
(acc, cur) => acc || evaluateCondition(data, cur, path, ajv),
false
);
} else if (isLeafCondition(condition)) {
Expand All @@ -86,18 +86,20 @@ const evaluateCondition = (
const isRuleFulfilled = (
uischema: UISchemaElement,
data: any,
path: string
path: string,
ajv: Ajv
): boolean => {
const condition = uischema.rule.condition;
return evaluateCondition(data, condition, path);
return evaluateCondition(data, condition, path, ajv);
};

export const evalVisibility = (
uischema: UISchemaElement,
data: any,
path: string = undefined
path: string = undefined,
ajv: Ajv = createAjv()
): boolean => {
const fulfilled = isRuleFulfilled(uischema, data, path);
const fulfilled = isRuleFulfilled(uischema, data, path, ajv);

switch (uischema.rule.effect) {
case RuleEffect.HIDE:
Expand All @@ -113,9 +115,10 @@ export const evalVisibility = (
export const evalEnablement = (
uischema: UISchemaElement,
data: any,
path: string = undefined
path: string = undefined,
ajv: Ajv = createAjv()
): boolean => {
const fulfilled = isRuleFulfilled(uischema, data, path);
const fulfilled = isRuleFulfilled(uischema, data, path, ajv);

switch (uischema.rule.effect) {
case RuleEffect.DISABLE:
Expand Down Expand Up @@ -153,10 +156,11 @@ export const hasEnableRule = (uischema: UISchemaElement): boolean => {
export const isVisible = (
uischema: UISchemaElement,
data: any,
path: string = undefined
path: string = undefined,
ajv: Ajv = createAjv()
): boolean => {
if (uischema.rule) {
return evalVisibility(uischema, data, path);
return evalVisibility(uischema, data, path, ajv);
}

return true;
Expand All @@ -165,10 +169,11 @@ export const isVisible = (
export const isEnabled = (
uischema: UISchemaElement,
data: any,
path: string = undefined
path: string = undefined,
ajv: Ajv = createAjv()
): boolean => {
if (uischema.rule) {
return evalEnablement(uischema, data, path);
return evalEnablement(uischema, data, path, ajv);
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ export class MaterialCategorizationLayoutRenderer extends RendererComponent<
uischema,
visible,
enabled,
selected
selected,
ajv
} = this.props;
const categorization = uischema as Categorization;
const value = this.hasOwnState() ? this.state.activeCategory : selected;
Expand All @@ -107,7 +108,7 @@ export class MaterialCategorizationLayoutRenderer extends RendererComponent<
cells
};
const categories = categorization.elements.filter((category: Category) =>
isVisible(category, data)
isVisible(category, data, undefined, ajv)
);
return (
<Hidden xsUp={!visible}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ export class MaterialCategorizationStepperLayoutRenderer extends RendererCompone
uischema,
visible,
cells,
config
config,
ajv
} = this.props;
const categorization = uischema as Categorization;
const activeCategory = this.state.activeCategory;
Expand All @@ -108,7 +109,7 @@ export class MaterialCategorizationStepperLayoutRenderer extends RendererCompone
cells
};
const categories = categorization.elements.filter((category: Category) =>
isVisible(category, data)
isVisible(category, data, undefined, ajv)
);
return (
<Hidden xsUp={!visible}>
Expand Down

0 comments on commit 57af381

Please sign in to comment.