@json-layout/core
Advanced tools
Comparing version 0.4.0 to 0.5.0
{ | ||
"name": "@json-layout/core", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "Compilation and state management utilities for JSON Layout.", | ||
@@ -50,3 +50,3 @@ "type": "module", | ||
"dependencies": { | ||
"@json-layout/vocabulary": "^0.4.0", | ||
"@json-layout/vocabulary": "^0.5.0", | ||
"@types/markdown-it": "^13.0.1", | ||
@@ -53,0 +53,0 @@ "ajv": "^8.12.0", |
@@ -30,4 +30,2 @@ // compileStatic is meant to produce a serializable result | ||
const expressionsParams = ['data', 'options', 'context', 'display'] | ||
// const exprEvalParser = new ExprEvalParser() | ||
@@ -118,2 +116,5 @@ | ||
for (const expression of expressionsDefinitions) { | ||
const expressionsParams = expression.pure | ||
? ['data', 'options', 'context', 'display'] | ||
: ['data', 'options', 'context', 'display', 'parentData', 'rootData'] | ||
/* if (expression.type === 'expr-eval') { | ||
@@ -120,0 +121,0 @@ expressions.push(exprEvalParser.parse(expression.expr).toJSFunction(expressionsParams.join(','))) |
@@ -6,16 +6,2 @@ // import Debug from 'debug' | ||
/** | ||
* @param {import('@json-layout/vocabulary').Expression[]} expressions | ||
* @param {import('@json-layout/vocabulary').Expression} expression | ||
*/ | ||
const pushExpression = (expressions, expression) => { | ||
const index = expressions.findIndex(e => e.type === expression.type && e.expr === expression.expr) | ||
if (index !== -1) { | ||
expression.ref = index | ||
} else { | ||
expression.ref = expressions.length | ||
expressions.push(expression) | ||
} | ||
} | ||
/** | ||
* @param {any} schema | ||
@@ -66,2 +52,18 @@ * @param {import('./index.js').CompileOptions} options | ||
let pure = true | ||
/** | ||
* @param {import('@json-layout/vocabulary').Expression[]} expressions | ||
* @param {import('@json-layout/vocabulary').Expression} expression | ||
*/ | ||
const pushExpression = (expressions, expression) => { | ||
if (!expression.pure) pure = false | ||
const index = expressions.findIndex(e => e.type === expression.type && e.expr === expression.expr) | ||
if (index !== -1) { | ||
expression.ref = index | ||
} else { | ||
expression.ref = expressions.length | ||
expressions.push(expression) | ||
} | ||
} | ||
const compObjects = isSwitchStruct(normalizedLayout) ? normalizedLayout.switch : [normalizedLayout] | ||
@@ -72,6 +74,6 @@ for (const compObject of compObjects) { | ||
if ('const' in schema) compObject.constData = { type: 'js-eval', expr: JSON.stringify(schema.const) } | ||
if ('const' in schema) compObject.constData = { type: 'js-eval', expr: JSON.stringify(schema.const), pure: true } | ||
if (compObject.constData) pushExpression(expressions, compObject.constData) | ||
if (defaultData && !compObject.defaultData) compObject.defaultData = { type: 'js-eval', expr: JSON.stringify(defaultData) } | ||
if (defaultData && !compObject.defaultData) compObject.defaultData = { type: 'js-eval', expr: JSON.stringify(defaultData), pure: true } | ||
if (compObject.defaultData) pushExpression(expressions, compObject.defaultData) | ||
@@ -91,3 +93,3 @@ | ||
/** @type {import('./types.js').SkeletonNode} */ | ||
const node = { key: key ?? '', pointer, parentPointer } | ||
const node = { key: key ?? '', pointer, parentPointer, pure } | ||
if (schema.type === 'object') { | ||
@@ -159,3 +161,3 @@ if (schema.properties) { | ||
node.children = node.children ?? [] | ||
node.children.push({ key: '$oneOf', pointer: `${pointer}/oneOf`, parentPointer: pointer, childrenTrees }) | ||
node.children.push({ key: '$oneOf', pointer: `${pointer}/oneOf`, parentPointer: pointer, childrenTrees, pure: childrenTrees[0].root.pure }) | ||
@@ -197,3 +199,7 @@ schema.errorMessage.oneOf = options.messages.errorOneOf | ||
} | ||
for (const child of node.children || []) if (!child.pure) node.pure = false | ||
for (const childTree of node.childrenTrees || []) if (!childTree.root.pure) node.pure = false | ||
return node | ||
} |
import type ajvModule from 'ajv' | ||
import type MarkdownIt from 'markdown-it' | ||
import { type NormalizedLayout, type StateNodeOptions } from '@json-layout/vocabulary' | ||
import { type NormalizedLayout, type StateNodeOptionsBase } from '@json-layout/vocabulary' | ||
import { type ValidateFunction, type SchemaObject, type ErrorObject } from 'ajv' | ||
@@ -8,3 +8,3 @@ import { type Display } from '../state/utils/display.js' | ||
export type CompiledExpression = (data: any, options: StateNodeOptions, context: object, display: Display) => any | ||
export type CompiledExpression = (data: any, options: StateNodeOptionsBase, context: object, display: Display, rootData?: unknown, parentData?: unknown) => any | ||
@@ -48,4 +48,5 @@ export interface CompileOptions { | ||
parentPointer: string | null | ||
pure: boolean | ||
children?: SkeletonNode[] // optional children in the case of arrays and object nodes | ||
childrenTrees?: SkeletonTree[] // other trees that can be instantiated with separate validation (for example in the case of new array items of oneOfs, etc) | ||
} |
// eslint-disable-next-line import/no-named-default | ||
import mittModule from 'mitt' | ||
import debug from 'debug' | ||
import { produce } from 'immer' | ||
import { evalExpression, producePatchedData } from './state-node.js' | ||
@@ -252,3 +253,5 @@ import { createStateTree } from './state-tree.js' | ||
autofocusTarget: this._autofocusTarget, | ||
initial: !this._lastCreateStateTreeContext | ||
initial: !this._lastCreateStateTreeContext, | ||
cacheKeys: this._lastCreateStateTreeContext?.cacheKeys ?? {}, | ||
rootData: this._data | ||
} | ||
@@ -273,2 +276,3 @@ this._stateTree = createStateTree( | ||
} | ||
this.activeItems = createStateTreeContext.activeItems | ||
} | ||
@@ -317,3 +321,3 @@ | ||
if (activateKey !== undefined) { | ||
this.activeItems[node.fullKey] = activateKey | ||
this.activeItems = produce(this.activeItems, draft => { draft[node.fullKey] = activateKey }) | ||
this._autofocusTarget = node.fullKey + '/' + activateKey | ||
@@ -374,3 +378,5 @@ } | ||
const evalSelectExpression = (expression, data) => { | ||
return evalExpression(this.compiledLayout.expressions, expression, data, node.options, new Display(node.options.width)) | ||
const parentNode = this._lastCreateStateTreeContext.nodes.find(n => n.fullKey === node.parentFullKey) | ||
const parentData = parentNode ? parentNode.data : null | ||
return evalExpression(this.compiledLayout.expressions, expression, data, node.options, new Display(node.width), parentData, this._data) | ||
} | ||
@@ -450,3 +456,3 @@ | ||
activateItem (node, key) { | ||
this.activeItems[node.fullKey] = key | ||
this.activeItems = produce(this.activeItems, draft => { draft[node.fullKey] = key }) | ||
this._autofocusTarget = node.fullKey + '/' + key | ||
@@ -465,3 +471,3 @@ if (node.key === '$oneOf') { | ||
deactivateItem (node) { | ||
delete this.activeItems[node.fullKey] | ||
this.activeItems = produce(this.activeItems, draft => { delete draft[node.fullKey] }) | ||
this.updateState() | ||
@@ -468,0 +474,0 @@ } |
import { isSwitchStruct, childIsCompObject, isCompositeLayout, isFocusableLayout } from '@json-layout/vocabulary' | ||
import { produce } from 'immer' | ||
import { getChildDisplay } from './utils/display.js' | ||
import { shallowCompareArrays } from './utils/immutable.js' | ||
import { shallowEqualArray, shallowProduceArray } from './utils/immutable.js' | ||
@@ -20,3 +20,3 @@ /** | ||
* @param {import('@json-layout/vocabulary').CompObject} layout | ||
* @param {import('./types.js').StatefulLayoutOptions} options | ||
* @param {import('./types.js').StateNodeOptions} options | ||
* @returns {boolean} | ||
@@ -31,4 +31,4 @@ */ | ||
// use Immer for efficient updating with immutability and no-op detection | ||
/** @type {(draft: import('./types.js').StateNode, key: string | number, fullKey: string, parentFullKey: string | null, dataPath: string, parentDataPath: string | null, skeleton: import('../index.js').SkeletonNode, layout: import('@json-layout/vocabulary').CompObject, cols: number, data: unknown, error: string | undefined, validated: boolean, options: import('./types.js').StatefulLayoutOptions, autofocus: boolean, children: import('../index.js').StateNode[] | undefined) => import('../index.js').StateNode} */ | ||
const produceStateNode = produce((draft, key, fullKey, parentFullKey, dataPath, parentDataPath, skeleton, layout, cols, data, error, validated, options, autofocus, children) => { | ||
/** @type {(draft: import('./types.js').StateNode, key: string | number, fullKey: string, parentFullKey: string | null, dataPath: string, parentDataPath: string | null, skeleton: import('../index.js').SkeletonNode, layout: import('@json-layout/vocabulary').CompObject, width: number, cols: number, data: unknown, error: string | undefined, validated: boolean, options: import('./types.js').StateNodeOptions, autofocus: boolean, children: import('../index.js').StateNode[] | undefined) => import('../index.js').StateNode} */ | ||
const produceStateNode = produce((draft, key, fullKey, parentFullKey, dataPath, parentDataPath, skeleton, layout, width, cols, data, error, validated, options, autofocus, children) => { | ||
draft.messages = layout.messages ? produceStateNodeMessages(draft.messages || {}, layout.messages, options) : options.messages | ||
@@ -43,2 +43,3 @@ | ||
draft.layout = layout | ||
draft.width = width | ||
draft.options = options | ||
@@ -63,3 +64,3 @@ draft.cols = cols | ||
/** @type {(draft: import('../i18n/types.js').LocaleMessages, layoutMessages: Partial<import('../i18n/types.js').LocaleMessages>, options: import('./types.js').StatefulLayoutOptions) => import('../i18n/types.js').LocaleMessages} */ | ||
/** @type {(draft: import('../i18n/types.js').LocaleMessages, layoutMessages: Partial<import('../i18n/types.js').LocaleMessages>, options: import('./types.js').StateNodeOptions) => import('../i18n/types.js').LocaleMessages} */ | ||
const produceStateNodeMessages = produce((draft, layoutMessages, options) => { | ||
@@ -83,6 +84,6 @@ Object.assign(draft, options.messages, layoutMessages) | ||
/** @type {(draft: import('./types.js').StatefulLayoutOptions, parentNodeOptions: import('./types.js').StatefulLayoutOptions, nodeOptions: import('@json-layout/vocabulary').StateNodeOptions | undefined, width: number) => import('./types.js').StatefulLayoutOptions} */ | ||
const produceNodeOptions = produce((draft, parentNodeOptions, nodeOptions = {}, width) => { | ||
/** @type {(draft: import('./types.js').StateNodeOptions, parentNodeOptions: import('./types.js').StateNodeOptions, nodeOptions: Partial<import('./types.js').StateNodeOptions> | undefined) => import('./types.js').StateNodeOptions} */ | ||
const produceNodeOptions = produce((draft, parentNodeOptions, nodeOptions = {}) => { | ||
for (const key in parentNodeOptions) { | ||
draft[key] = parentNodeOptions[key] | ||
draft[key] = nodeOptions[key] ?? parentNodeOptions[key] | ||
} | ||
@@ -98,6 +99,5 @@ for (const key in nodeOptions) { | ||
} | ||
draft.width = width | ||
}) | ||
/** @type {(draft: import('./types.js').StatefulLayoutOptions) => import('./types.js').StatefulLayoutOptions} */ | ||
/** @type {(draft: import('./types.js').StateNodeOptions) => import('./types.js').StateNodeOptions} */ | ||
const produceReadonlyArrayItemOptions = produce((draft) => { | ||
@@ -108,3 +108,3 @@ draft.readOnly = true | ||
/** @type {(draft: import('./types.js').StatefulLayoutOptions, section: import('@json-layout/vocabulary').CompositeCompObject) => import('./types.js').StatefulLayoutOptions} */ | ||
/** @type {(draft: import('./types.js').StateNodeOptions, section: import('@json-layout/vocabulary').CompositeCompObject) => import('./types.js').StateNodeOptions} */ | ||
const produceCompositeChildrenOptions = produce((draft, section) => { | ||
@@ -144,11 +144,12 @@ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands | ||
* @param {any} data | ||
* @param {import('./types.js').StatefulLayoutOptions} options | ||
* @param {import('./types.js').StateNodeOptions} options | ||
* @param {import('./utils/display.js').Display} display | ||
* @param {unknown} rootData | ||
* @param {unknown} parentData | ||
* @returns {any} | ||
*/ | ||
export function evalExpression (expressions, expression, data, options, display) { | ||
export function evalExpression (expressions, expression, data, options, display, rootData, parentData) { | ||
if (expression.ref === undefined) throw new Error('expression was not compiled : ' + JSON.stringify(expression)) | ||
const compiledExpression = expressions[expression.ref] | ||
// console.log(expression.expr, context, mode, display) | ||
return compiledExpression(data, options, options.context, display) | ||
return expression.pure ? compiledExpression(data, options, options.context, display) : compiledExpression(data, options, options.context, display, rootData, parentData) | ||
} | ||
@@ -158,12 +159,14 @@ | ||
* @param {import('@json-layout/vocabulary').NormalizedLayout} normalizedLayout | ||
* @param {import('./types.js').StatefulLayoutOptions} options | ||
* @param {import('./types.js').StateNodeOptions} options | ||
* @param {import('../index.js').CompiledLayout} compiledLayout | ||
* @param {import('./utils/display.js').Display} display | ||
* @param {unknown} data | ||
* @param {unknown} rootData | ||
* @param {unknown} parentData | ||
* @returns {import('@json-layout/vocabulary').CompObject} | ||
*/ | ||
const getCompObject = (normalizedLayout, options, compiledLayout, display, data) => { | ||
const getCompObject = (normalizedLayout, options, compiledLayout, display, data, rootData, parentData) => { | ||
if (isSwitchStruct(normalizedLayout)) { | ||
for (const compObject of normalizedLayout.switch) { | ||
if (!compObject.if || !!evalExpression(compiledLayout.expressions, compObject.if, data, options, display)) { | ||
if (!compObject.if || !!evalExpression(compiledLayout.expressions, compObject.if, data, options, display, parentData, rootData)) { | ||
return compObject | ||
@@ -173,5 +176,11 @@ } | ||
} else { | ||
return normalizedLayout | ||
if (normalizedLayout.if) { | ||
if (evalExpression(compiledLayout.expressions, normalizedLayout.if, data, options, display, parentData, rootData)) { | ||
return normalizedLayout | ||
} | ||
} else { | ||
return normalizedLayout | ||
} | ||
} | ||
throw new Error('no layout matched for node') | ||
return { comp: 'none' } | ||
} | ||
@@ -182,3 +191,3 @@ | ||
* @param {import('./types.js').CreateStateTreeContext} context | ||
* @param {import('./types.js').StatefulLayoutOptions} parentOptions | ||
* @param {import('./types.js').StateNodeOptions} parentOptions | ||
* @param {import('../index.js').CompiledLayout} compiledLayout | ||
@@ -194,2 +203,3 @@ * @param {string | number} key | ||
* @param {unknown} data | ||
* @param {unknown} parentData | ||
* @param {import('./types.js').ValidationState} validationState | ||
@@ -212,19 +222,31 @@ * @param {import('./types.js').StateNode} [reusedNode] | ||
data, | ||
parentData, | ||
validationState, | ||
reusedNode | ||
) { | ||
/** @type {import('./types.js').StateNodeCacheKey | null} */ | ||
let cacheKey = null | ||
if (skeleton.pure && reusedNode) { | ||
cacheKey = [parentOptions, compiledLayout, fullKey, skeleton, childDefinition, parentDisplay.width, validationState, context.activeItems, context.initial, data] | ||
if (context.cacheKeys[fullKey] && shallowEqualArray(context.cacheKeys[fullKey], cacheKey)) { | ||
context.nodes.push(reusedNode) | ||
return reusedNode | ||
} | ||
} | ||
const normalizedLayout = childDefinition && childIsCompObject(childDefinition) | ||
? childDefinition | ||
: compiledLayout.normalizedLayouts[skeleton.pointer] | ||
const layout = getCompObject(normalizedLayout, parentOptions, compiledLayout, parentDisplay, data) | ||
const layout = getCompObject(normalizedLayout, parentOptions, compiledLayout, parentDisplay, data, context.rootData, parentData) | ||
const [display, cols] = getChildDisplay(parentDisplay, childDefinition?.cols ?? layout.cols) | ||
const options = produceNodeOptions( | ||
reusedNode?.options ?? /** @type {import('./types.js').StatefulLayoutOptions} */({}), | ||
parentOptions, | ||
layout.options, | ||
display.width | ||
) | ||
const options = layout.options | ||
? produceNodeOptions( | ||
reusedNode?.options ?? /** @type {import('./types.js').StateNodeOptions} */({}), | ||
parentOptions, | ||
layout.options | ||
) | ||
: parentOptions | ||
if (context.initial && parentOptions.autofocus && layout.autofocus) { | ||
if (context.initial && parentOptions.autofocus && layout.autofocus && layout.comp !== 'none') { | ||
context.autofocusTarget = fullKey | ||
@@ -260,2 +282,3 @@ } | ||
isSameData ? objectData : objectData[childLayout.key], | ||
objectData, | ||
validationState, | ||
@@ -274,3 +297,3 @@ reusedNode?.children?.[i] | ||
if (activeChildTreeIndex !== -1) { | ||
context.activeItems[fullKey] = activeChildTreeIndex | ||
context.activeItems = produce(context.activeItems, draft => { draft[fullKey] = activeChildTreeIndex }) | ||
const activeChildKey = `${fullKey}/${activeChildTreeIndex}` | ||
@@ -293,2 +316,3 @@ if (context.autofocusTarget === fullKey) context.autofocusTarget = activeChildKey | ||
data, | ||
data, | ||
validationState, | ||
@@ -324,2 +348,3 @@ reusedNode?.children?.[0] | ||
itemData, | ||
arrayData, | ||
validationState, | ||
@@ -345,6 +370,6 @@ reusedNode?.children?.[0] | ||
if (layout.constData) { | ||
nodeData = evalExpression(compiledLayout.expressions, layout.constData, nodeData, options, display) | ||
nodeData = evalExpression(compiledLayout.expressions, layout.constData, nodeData, options, display, context.rootData, parentData) | ||
} else { | ||
if (layout.defaultData && useDefaultData(nodeData, layout, options)) { | ||
nodeData = evalExpression(compiledLayout.expressions, layout.defaultData, nodeData, options, display) | ||
nodeData = evalExpression(compiledLayout.expressions, layout.defaultData, nodeData, options, display, context.rootData, parentData) | ||
} else { | ||
@@ -376,2 +401,3 @@ if (isDataEmpty(nodeData)) { | ||
layout, | ||
display.width, | ||
cols, | ||
@@ -383,5 +409,8 @@ nodeData, | ||
autofocus, | ||
children && shallowCompareArrays(reusedNode?.children, children) | ||
children && shallowProduceArray(reusedNode?.children, children) | ||
) | ||
context.nodes.push(node) | ||
if (cacheKey) context.cacheKeys[fullKey] = cacheKey | ||
return node | ||
@@ -388,0 +417,0 @@ } |
@@ -54,2 +54,3 @@ import { produce } from 'immer' | ||
data, | ||
null, | ||
validationState, | ||
@@ -56,0 +57,0 @@ reusedStateTree?.root |
@@ -5,3 +5,3 @@ import { type ErrorObject } from 'ajv' | ||
type Cols, | ||
type StateNodeOptions, | ||
type StateNodeOptionsBase, | ||
type TextField, | ||
@@ -26,5 +26,6 @@ type Textarea, | ||
type List, | ||
type Combobox | ||
type Combobox, | ||
type Child | ||
} from '@json-layout/vocabulary' | ||
import { type SkeletonTree, type SkeletonNode, type StatefulLayout } from '../index.js' | ||
import { type SkeletonTree, type SkeletonNode, type StatefulLayout, type CompiledLayout } from '../index.js' | ||
import { type LocaleMessages } from '../i18n/types.js' | ||
@@ -45,3 +46,4 @@ | ||
validated: boolean | ||
options: StatefulLayoutOptions | ||
width: number | ||
options: StateNodeOptions | ||
messages: LocaleMessages | ||
@@ -65,4 +67,20 @@ autofocus?: boolean | ||
initial: boolean | ||
cacheKeys: Record<string, StateNodeCacheKey> | ||
rootData: unknown | ||
} | ||
// [parentOptions, compiledLayout, fullKey, skeleton, childDefinition, parentWidth, validationState, activeItems, initial, data] | ||
export type StateNodeCacheKey = [ | ||
StateNodeOptions, | ||
CompiledLayout, | ||
string, | ||
SkeletonNode, | ||
Child | null, | ||
number, | ||
ValidationState, | ||
Record<string, number>, | ||
boolean, | ||
unknown | ||
] | ||
export interface ValidationState { | ||
@@ -82,5 +100,4 @@ initialized: boolean | ||
export type StatefulLayoutOptions = Required<StateNodeOptions> & { | ||
export type StateNodeOptions = Required<StateNodeOptionsBase & { | ||
context: Record<string, any> | ||
width: number | ||
validateOn: 'input' | 'blur' | 'submit' | ||
@@ -91,2 +108,6 @@ initialValidation: 'never' | 'always' | 'withData' | ||
autofocus: boolean | ||
}> | ||
export type StatefulLayoutOptions = StateNodeOptions & { | ||
width: number | ||
} | ||
@@ -93,0 +114,0 @@ |
@@ -7,3 +7,3 @@ /** | ||
*/ | ||
export function shallowCompareArrays (a1 = [], a2 = []) { | ||
export function shallowProduceArray (a1 = [], a2 = []) { | ||
if (!a1 || !a2 || a1.length !== a2.length) return a2 | ||
@@ -13,1 +13,13 @@ for (let i = 0; i < a1.length; i++) { if (a1[i] !== a2[i]) return a2 } | ||
} | ||
/** | ||
* @template ItemType | ||
* @param {any[]} a1 | ||
* @param {any[]} a2 | ||
* @returns {boolean} | ||
*/ | ||
export function shallowEqualArray (a1 = [], a2 = []) { | ||
if (a1.length !== a2.length) return false | ||
for (let i = 0; i < a1.length; i++) { if (a1[i] !== a2[i]) return false } | ||
return true | ||
} |
import type ajvModule from 'ajv'; | ||
import type MarkdownIt from 'markdown-it'; | ||
import { type NormalizedLayout, type StateNodeOptions } from '@json-layout/vocabulary'; | ||
import { type NormalizedLayout, type StateNodeOptionsBase } from '@json-layout/vocabulary'; | ||
import { type ValidateFunction, type SchemaObject } from 'ajv'; | ||
import { type Display } from '../state/utils/display.js'; | ||
import { type LocaleMessages } from '../i18n/types.js'; | ||
export type CompiledExpression = (data: any, options: StateNodeOptions, context: object, display: Display) => any; | ||
export type CompiledExpression = (data: any, options: StateNodeOptionsBase, context: object, display: Display, rootData?: unknown, parentData?: unknown) => any; | ||
export interface CompileOptions { | ||
@@ -39,2 +39,3 @@ ajv: ajvModule.default; | ||
parentPointer: string | null; | ||
pure: boolean; | ||
children?: SkeletonNode[]; | ||
@@ -41,0 +42,0 @@ childrenTrees?: SkeletonTree[]; |
@@ -5,11 +5,13 @@ /** | ||
* @param {any} data | ||
* @param {import('./types.js').StatefulLayoutOptions} options | ||
* @param {import('./types.js').StateNodeOptions} options | ||
* @param {import('./utils/display.js').Display} display | ||
* @param {unknown} rootData | ||
* @param {unknown} parentData | ||
* @returns {any} | ||
*/ | ||
export function evalExpression(expressions: import('../index.js').CompiledExpression[], expression: import('@json-layout/vocabulary').Expression, data: any, options: import('./types.js').StatefulLayoutOptions, display: import('./utils/display.js').Display): any; | ||
export function evalExpression(expressions: import('../index.js').CompiledExpression[], expression: import('@json-layout/vocabulary').Expression, data: any, options: import('./types.js').StateNodeOptions, display: import('./utils/display.js').Display, rootData: unknown, parentData: unknown): any; | ||
/** | ||
* | ||
* @param {import('./types.js').CreateStateTreeContext} context | ||
* @param {import('./types.js').StatefulLayoutOptions} parentOptions | ||
* @param {import('./types.js').StateNodeOptions} parentOptions | ||
* @param {import('../index.js').CompiledLayout} compiledLayout | ||
@@ -25,2 +27,3 @@ * @param {string | number} key | ||
* @param {unknown} data | ||
* @param {unknown} parentData | ||
* @param {import('./types.js').ValidationState} validationState | ||
@@ -30,5 +33,5 @@ * @param {import('./types.js').StateNode} [reusedNode] | ||
*/ | ||
export function createStateNode(context: import('./types.js').CreateStateTreeContext, parentOptions: import('./types.js').StatefulLayoutOptions, compiledLayout: import('../index.js').CompiledLayout, key: string | number, fullKey: string, parentFullKey: string | null, dataPath: string, parentDataPath: string | null, skeleton: import('../index.js').SkeletonNode, childDefinition: import('@json-layout/vocabulary').Child | null, parentDisplay: import('./utils/display.js').Display, data: unknown, validationState: import('./types.js').ValidationState, reusedNode?: import("./types.js").StateNode | undefined): import('./types.js').StateNode; | ||
export function createStateNode(context: import('./types.js').CreateStateTreeContext, parentOptions: import('./types.js').StateNodeOptions, compiledLayout: import('../index.js').CompiledLayout, key: string | number, fullKey: string, parentFullKey: string | null, dataPath: string, parentDataPath: string | null, skeleton: import('../index.js').SkeletonNode, childDefinition: import('@json-layout/vocabulary').Child | null, parentDisplay: import('./utils/display.js').Display, data: unknown, parentData: unknown, validationState: import('./types.js').ValidationState, reusedNode?: import("./types.js").StateNode | undefined): import('./types.js').StateNode; | ||
/** @type {(draft: any, node: import('./types.js').StateNode, data: unknown) => any} */ | ||
export const producePatchedData: (draft: any, node: import('./types.js').StateNode, data: unknown) => any; | ||
//# sourceMappingURL=state-node.d.ts.map |
import { type ErrorObject } from 'ajv'; | ||
import { type CompObject, type Cols, type StateNodeOptions, type TextField, type Textarea, type NumberField, type Slider, type Checkbox, type Switch, type DatePicker, type DateTimePicker, type TimePicker, type ColorPicker, type Section, type OneOfSelect, type Select, type Autocomplete, type Tabs, type VerticalTabs, type ExpansionPanels, type Stepper, type List, type Combobox } from '@json-layout/vocabulary'; | ||
import { type SkeletonTree, type SkeletonNode, type StatefulLayout } from '../index.js'; | ||
import { type CompObject, type Cols, type StateNodeOptionsBase, type TextField, type Textarea, type NumberField, type Slider, type Checkbox, type Switch, type DatePicker, type DateTimePicker, type TimePicker, type ColorPicker, type Section, type OneOfSelect, type Select, type Autocomplete, type Tabs, type VerticalTabs, type ExpansionPanels, type Stepper, type List, type Combobox, type Child } from '@json-layout/vocabulary'; | ||
import { type SkeletonTree, type SkeletonNode, type StatefulLayout, type CompiledLayout } from '../index.js'; | ||
import { type LocaleMessages } from '../i18n/types.js'; | ||
@@ -18,3 +18,4 @@ export interface StateNode { | ||
validated: boolean; | ||
options: StatefulLayoutOptions; | ||
width: number; | ||
options: StateNodeOptions; | ||
messages: LocaleMessages; | ||
@@ -36,3 +37,17 @@ autofocus?: boolean; | ||
initial: boolean; | ||
cacheKeys: Record<string, StateNodeCacheKey>; | ||
rootData: unknown; | ||
} | ||
export type StateNodeCacheKey = [ | ||
StateNodeOptions, | ||
CompiledLayout, | ||
string, | ||
SkeletonNode, | ||
Child | null, | ||
number, | ||
ValidationState, | ||
Record<string, number>, | ||
boolean, | ||
unknown | ||
]; | ||
export interface ValidationState { | ||
@@ -48,5 +63,4 @@ initialized: boolean; | ||
}; | ||
export type StatefulLayoutOptions = Required<StateNodeOptions> & { | ||
export type StateNodeOptions = Required<StateNodeOptionsBase & { | ||
context: Record<string, any>; | ||
width: number; | ||
validateOn: 'input' | 'blur' | 'submit'; | ||
@@ -57,2 +71,5 @@ initialValidation: 'never' | 'always' | 'withData'; | ||
autofocus: boolean; | ||
}>; | ||
export type StatefulLayoutOptions = StateNodeOptions & { | ||
width: number; | ||
}; | ||
@@ -59,0 +76,0 @@ export type TextFieldNode = Omit<StateNode, 'children'> & { |
@@ -7,3 +7,10 @@ /** | ||
*/ | ||
export function shallowCompareArrays<ItemType>(a1?: ItemType[], a2?: ItemType[]): ItemType[]; | ||
export function shallowProduceArray<ItemType>(a1?: ItemType[], a2?: ItemType[]): ItemType[]; | ||
/** | ||
* @template ItemType | ||
* @param {any[]} a1 | ||
* @param {any[]} a2 | ||
* @returns {boolean} | ||
*/ | ||
export function shallowEqualArray<ItemType>(a1?: any[], a2?: any[]): boolean; | ||
//# sourceMappingURL=immutable.d.ts.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
108968
2439
+ Added@json-layout/vocabulary@0.5.0(transitive)
- Removed@json-layout/vocabulary@0.4.0(transitive)