Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@json-layout/core

Package Overview
Dependencies
Maintainers
1
Versions
54
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@json-layout/core - npm Package Compare versions

Comparing version 0.5.0 to 0.6.0

4

package.json
{
"name": "@json-layout/core",
"version": "0.5.0",
"version": "0.6.0",
"description": "Compilation and state management utilities for JSON Layout.",

@@ -50,3 +50,3 @@ "type": "module",

"dependencies": {
"@json-layout/vocabulary": "^0.5.0",
"@json-layout/vocabulary": "^0.6.0",
"@types/markdown-it": "^13.0.1",

@@ -53,0 +53,0 @@ "ajv": "^8.12.0",

@@ -78,2 +78,4 @@ // import Debug from 'debug'

if (compObject.transformData) pushExpression(expressions, compObject.transformData)
if (isItemsLayout(compObject) && compObject.getItems) {

@@ -80,0 +82,0 @@ if (isGetItemsExpression(compObject.getItems)) pushExpression(expressions, compObject.getItems)

@@ -8,3 +8,4 @@ // eslint-disable-next-line import/no-named-default

import { Display } from './utils/display.js'
import { isGetItemsExpression, isGetItemsFetch, isItemsLayout } from '@json-layout/vocabulary'
import { isFileLayout, isGetItemsExpression, isGetItemsFetch, isItemsLayout } from '@json-layout/vocabulary'
import { shallowProduceArray } from './utils/immutable.js'

@@ -39,2 +40,3 @@ export { Display } from './utils/display.js'

* @typedef {import('./types.js').ListNode} ListNode
* @typedef {import('./types.js').FileRef} FileRef
*/

@@ -189,2 +191,7 @@

/**
* @type {FileRef[]}
*/
files = []
/**
* @param {import("../index.js").CompiledLayout} compiledLayout

@@ -253,3 +260,2 @@ * @param {import("../index.js").SkeletonTree} skeletonTree

const createStateTreeContext = {
nodes: [],
activeItems: this.activeItems,

@@ -259,3 +265,5 @@ autofocusTarget: this._autofocusTarget,

cacheKeys: this._lastCreateStateTreeContext?.cacheKeys ?? {},
rootData: this._data
rootData: this._data,
files: [],
nodes: []
}

@@ -281,2 +289,3 @@ this._stateTree = createStateTree(

this.activeItems = createStateTreeContext.activeItems
this.files = shallowProduceArray(this.files, createStateTreeContext.files)
}

@@ -315,3 +324,17 @@

/**
* @private
* @param {StateNode} node
* @param {import('@json-layout/vocabulary').Expression} expression
* @param {any} data
* @returns {any}
*/
evalNodeExpression = (node, expression, data) => {
// const parentNode = this._stateTree.traverseNode(this._stateTree.root).find(n => n.fullKey === node.parentFullKey)
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)
}
/**
* @param {StateNode} node
* @param {unknown} data

@@ -322,2 +345,24 @@ * @param {number} [activateKey]

logDataBinding('received input event from node', node, data)
const transformedData = node.layout.transformData && this.evalNodeExpression(node, node.layout.transformData, data)
if (isFileLayout(node.layout)) {
if (transformedData) {
// @ts-ignore
data.toJSON = () => transformedData
} else if (data instanceof File) {
const fileJSON = { name: data.name, size: data.size, type: data.type }
// @ts-ignore
data.toJSON = () => fileJSON
} else if (Array.isArray(data)) {
for (const file of data) {
const fileJSON = { name: file.name, size: file.size, type: file.type }
// @ts-ignore
file.toJSON = () => fileJSON
}
}
} else if (transformedData) {
data = transformedData
}
if (node.options.validateOn === 'input' && !this.validationState.validatedChildren.includes(node.fullKey)) {

@@ -381,17 +426,10 @@ this.validationState = { validatedChildren: this.validationState.validatedChildren.concat([node.fullKey]) }

/** @type {(expression: import('@json-layout/vocabulary').Expression, data: any) => any} */
const evalSelectExpression = (expression, data) => {
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)
}
let rawItems
let appliedQ = false
if (node.layout.getItems && isGetItemsExpression(node.layout.getItems)) {
rawItems = evalSelectExpression(node.layout.getItems, null)
rawItems = this.evalNodeExpression(node, node.layout.getItems, null)
if (!Array.isArray(rawItems)) throw new Error('getItems expression didn\'t return an array')
}
if (node.layout.getItems && isGetItemsFetch(node.layout.getItems)) {
const url = new URL(evalSelectExpression(node.layout.getItems.url, null))
const url = new URL(this.evalNodeExpression(node, node.layout.getItems.url, null))
let qSearchParam = node.layout.getItems.qSearchParam

@@ -413,3 +451,3 @@ if (!qSearchParam) {

if (node.layout.getItems?.itemsResults) {
rawItems = evalSelectExpression(node.layout.getItems.itemsResults, rawItems)
rawItems = this.evalNodeExpression(node, node.layout.getItems.itemsResults, rawItems)
}

@@ -421,5 +459,5 @@ /** @type {import('@json-layout/vocabulary').SelectItems} */

if (typeof rawItem === 'object') {
item.value = node.layout.getItems?.itemValue ? evalSelectExpression(node.layout.getItems.itemValue, rawItem) : (node.layout.getItems?.returnObjects ? rawItem : rawItem.value)
item.key = node.layout.getItems?.itemKey ? evalSelectExpression(node.layout.getItems.itemKey, rawItem) : rawItem.key
item.title = node.layout.getItems?.itemTitle ? evalSelectExpression(node.layout.getItems.itemTitle, rawItem) : rawItem.title
item.value = node.layout.getItems?.itemValue ? this.evalNodeExpression(node, node.layout.getItems.itemValue, rawItem) : (node.layout.getItems?.returnObjects ? rawItem : rawItem.value)
item.key = node.layout.getItems?.itemKey ? this.evalNodeExpression(node, node.layout.getItems.itemKey, rawItem) : rawItem.key
item.title = node.layout.getItems?.itemTitle ? this.evalNodeExpression(node, node.layout.getItems.itemTitle, rawItem) : rawItem.title
item.value = item.value ?? item.key

@@ -430,7 +468,7 @@ item.key = item.key ?? item.value + ''

} else {
item.value = node.layout.getItems?.itemValue ? evalSelectExpression(node.layout.getItems.itemValue, rawItem) : rawItem
item.key = node.layout.getItems?.itemKey ? evalSelectExpression(node.layout.getItems.itemKey, rawItem) : item.value
item.title = node.layout.getItems?.itemTitle ? evalSelectExpression(node.layout.getItems.itemTitle, rawItem) : item.value
item.value = node.layout.getItems?.itemValue ? this.evalNodeExpression(node, node.layout.getItems.itemValue, rawItem) : rawItem
item.key = node.layout.getItems?.itemKey ? this.evalNodeExpression(node, node.layout.getItems.itemKey, rawItem) : item.value
item.title = node.layout.getItems?.itemTitle ? this.evalNodeExpression(node, node.layout.getItems.itemTitle, rawItem) : item.value
}
if (node.layout.getItems?.itemIcon) item.icon = evalSelectExpression(node.layout.getItems?.itemIcon, rawItem)
if (node.layout.getItems?.itemIcon) item.icon = this.evalNodeExpression(node, node.layout.getItems?.itemIcon, rawItem)
return item

@@ -437,0 +475,0 @@ })

@@ -218,6 +218,3 @@ import { isSwitchStruct, childIsCompObject, isCompositeLayout, isFocusableLayout } from '@json-layout/vocabulary'

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
}
if (context.cacheKeys[fullKey] && shallowEqualArray(context.cacheKeys[fullKey], cacheKey)) return reusedNode
}

@@ -394,3 +391,2 @@

context.nodes.push(node)
if (cacheKey) context.cacheKeys[fullKey] = cacheKey

@@ -397,0 +393,0 @@

@@ -13,2 +13,17 @@ import { produce } from 'immer'

/**
* @generator
* @param {import('./types.js').StateNode} node
* @yields {import('./types.js').StateNode}
* @returns {Generator<import('./types.js').StateNode>}
*/
function * traverseNodes (node) {
yield node
if (node.children) {
for (const child of node.children) {
yield * traverseNodes(child)
}
}
}
/**
* @param {import('./types.js').CreateStateTreeContext} context

@@ -60,3 +75,12 @@ * @param {import('./types.js').StatefulLayoutOptions} options

context.nodes = []
context.files = []
for (const node of traverseNodes(root)) {
context.nodes.push(node)
if (node.data instanceof File) {
context.files.push({ dataPath: node.dataPath, file: node.data })
}
}
return produceStateTree(reusedStateTree ?? /** @type {import('./types.js').StateTree} */({}), root, valid)
}

@@ -55,3 +55,2 @@ import { type ErrorObject } from 'ajv'

valid: boolean
title: string
}

@@ -61,3 +60,3 @@

errors?: ErrorObject[]
nodes: StateNode[]
files: FileRef[]
activeItems: Record<string, number>

@@ -68,4 +67,10 @@ autofocusTarget: string | null

rootData: unknown
nodes: StateNode[]
}
export interface FileRef {
file: File
dataPath: string
}
// [parentOptions, compiledLayout, fullKey, skeleton, childDefinition, parentWidth, validationState, activeItems, initial, data]

@@ -72,0 +77,0 @@ export type StateNodeCacheKey = [

/**
* @template ItemType
* @param {ItemType[]} a1
* @param {ItemType[]} a2
* @param {ItemType[]} previousArray
* @param {ItemType[]} newArray
* @returns {ItemType[]}
*/
export function shallowProduceArray (a1 = [], a2 = []) {
if (!a1 || !a2 || a1.length !== a2.length) return a2
for (let i = 0; i < a1.length; i++) { if (a1[i] !== a2[i]) return a2 }
return a1
export function shallowProduceArray (previousArray = [], newArray = []) {
if (!previousArray || !newArray || previousArray.length !== newArray.length) return newArray
for (let i = 0; i < previousArray.length; i++) { if (previousArray[i] !== newArray[i]) return newArray }
return previousArray
}

@@ -12,0 +12,0 @@

@@ -28,2 +28,3 @@ export { Display } from "./utils/display.js";

* @typedef {import('./types.js').ListNode} ListNode
* @typedef {import('./types.js').FileRef} FileRef
*/

@@ -121,2 +122,6 @@ /** @type {(node: StateNode | undefined) => node is SectionNode} */

/**
* @type {FileRef[]}
*/
files: FileRef[];
/**
* @type {Record<string, number>}

@@ -157,3 +162,11 @@ */

/**
* @private
* @param {StateNode} node
* @param {import('@json-layout/vocabulary').Expression} expression
* @param {any} data
* @returns {any}
*/
private evalNodeExpression;
/**
* @param {StateNode} node
* @param {unknown} data

@@ -220,3 +233,4 @@ * @param {number} [activateKey]

export type ListNode = import('./types.js').ListNode;
export type FileRef = import('./types.js').FileRef;
import { Display } from './utils/display.js';
//# sourceMappingURL=index.d.ts.map

@@ -28,7 +28,6 @@ import { type ErrorObject } from 'ajv';

valid: boolean;
title: string;
}
export interface CreateStateTreeContext {
errors?: ErrorObject[];
nodes: StateNode[];
files: FileRef[];
activeItems: Record<string, number>;

@@ -39,3 +38,8 @@ autofocusTarget: string | null;

rootData: unknown;
nodes: StateNode[];
}
export interface FileRef {
file: File;
dataPath: string;
}
export type StateNodeCacheKey = [

@@ -42,0 +46,0 @@ StateNodeOptions,

/**
* @template ItemType
* @param {ItemType[]} a1
* @param {ItemType[]} a2
* @param {ItemType[]} previousArray
* @param {ItemType[]} newArray
* @returns {ItemType[]}
*/
export function shallowProduceArray<ItemType>(a1?: ItemType[], a2?: ItemType[]): ItemType[];
export function shallowProduceArray<ItemType>(previousArray?: ItemType[], newArray?: ItemType[]): ItemType[];
/**

@@ -9,0 +9,0 @@ * @template ItemType

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc