@webiny/website-builder-sdk 6.0.0-rc.7 → 6.1.0-beta.0
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/BindingsResolver.js +1 -4
- package/BindingsResolver.js.map +1 -1
- package/ComponentRegistry.js +30 -0
- package/ComponentRegistry.js.map +1 -1
- package/ConstraintEvaluator.d.ts +36 -0
- package/ConstraintEvaluator.js +395 -0
- package/ConstraintEvaluator.js.map +1 -0
- package/ConstraintEvaluator.test.d.ts +1 -0
- package/ConstraintEvaluator.test.js +1456 -0
- package/ConstraintEvaluator.test.js.map +1 -0
- package/ElementFactory.d.ts +2 -3
- package/ElementFactory.js +21 -12
- package/ElementFactory.js.map +1 -1
- package/ElementFactory.test.d.ts +1 -0
- package/ElementFactory.test.js +280 -0
- package/ElementFactory.test.js.map +1 -0
- package/InputBindingsProcessor.js +24 -6
- package/InputBindingsProcessor.js.map +1 -1
- package/InputsBindingsProcessor.test.js +1 -0
- package/InputsBindingsProcessor.test.js.map +1 -1
- package/documentOperations/$addElementReferenceToParent.d.ts +1 -1
- package/documentOperations/$addElementReferenceToParent.js +9 -2
- package/documentOperations/$addElementReferenceToParent.js.map +1 -1
- package/documentOperations/AddToParent.d.ts +2 -2
- package/documentOperations/AddToParent.js.map +1 -1
- package/documentOperations/RemoveElement.js +9 -0
- package/documentOperations/RemoveElement.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/messenger/Messenger.js +1 -3
- package/messenger/Messenger.js.map +1 -1
- package/package.json +8 -8
- package/types.d.ts +120 -7
- package/types.js.map +1 -1
package/BindingsResolver.js
CHANGED
|
@@ -108,10 +108,7 @@ export class BindingsResolver {
|
|
|
108
108
|
if (binding.expression) {
|
|
109
109
|
return this.evaluateExpression(binding.expression, context);
|
|
110
110
|
}
|
|
111
|
-
|
|
112
|
-
return binding.static;
|
|
113
|
-
}
|
|
114
|
-
return undefined;
|
|
111
|
+
return binding.static;
|
|
115
112
|
}
|
|
116
113
|
evaluateExpression(expression, context = {}) {
|
|
117
114
|
if (!expression || expression === "$noop") {
|
package/BindingsResolver.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["toJS","BindingsResolver","constructor","state","resolveElement","element","elementBindings","inputAst","onResolved","repeatBindingArray","$repeat","items","resolveBinding","Array","isArray","map","item","resolveSingleInstance","undefined","resolvedElement","id","inputs","styles","context","$","bindings","resolveInputsFromAst","nodes","prefix","target","node","pathParts","name","path","join","binding","value","input","defaultValue","finalValue","children","length","list","uniqueIndexes","getUniqueIndexesFromPath","index","childTarget","slice","resolvedStyles","Object","entries","flatKey","pattern","RegExp","indexes","keys","reduce","acc","key","match","push","parseInt","from","Set","sort","a","b","expression","evaluateExpression","static","finalExpression","trim","startsWith","replace","scopedFn","Function","values"],"sources":["BindingsResolver.ts"],"sourcesContent":["import { toJS } from \"mobx\";\nimport type {\n ComponentInput,\n DocumentElement,\n DocumentElementBindings,\n DocumentElementStyleBindings,\n DocumentState,\n ResolvedElement,\n SerializableCSSStyleDeclaration,\n ValueBinding\n} from \"~/types.js\";\nimport type { InputAstNode } from \"./ComponentManifestToAstConverter.js\";\n\nexport interface OnResolved {\n (value: any, input: ComponentInput): any;\n}\n\nexport type ResolveElementParams = {\n element: DocumentElement;\n elementBindings: DocumentElementBindings;\n inputAst: InputAstNode[];\n onResolved?: OnResolved;\n};\n\nexport class BindingsResolver {\n private readonly state: DocumentState;\n\n constructor(state: DocumentState) {\n this.state = state;\n }\n\n public resolveElement({\n element,\n elementBindings,\n inputAst,\n onResolved\n }: ResolveElementParams): ResolvedElement[] {\n const repeatBindingArray = elementBindings.$repeat;\n\n if (repeatBindingArray) {\n const items = this.resolveBinding(repeatBindingArray, { state: toJS(this.state) });\n\n if (!Array.isArray(items)) {\n return [];\n }\n\n return items.map(item => {\n return this.resolveSingleInstance(\n element,\n elementBindings,\n item,\n inputAst,\n onResolved\n );\n });\n }\n\n return [\n this.resolveSingleInstance(element, elementBindings, undefined, inputAst, onResolved)\n ];\n }\n\n private resolveSingleInstance(\n element: DocumentElement,\n elementBindings: DocumentElementBindings,\n item: Record<string, any> | undefined,\n inputAst: InputAstNode[],\n onResolved?: OnResolved\n ): ResolvedElement {\n const resolvedElement: ResolvedElement = {\n id: element.id,\n inputs: {},\n styles: {}\n };\n\n const context = { state: this.state, $: item };\n const bindings = elementBindings.inputs ?? {};\n\n const resolveInputsFromAst = (\n nodes: InputAstNode[],\n prefix: string[],\n target: Record<string, any>\n ) => {\n for (const node of nodes) {\n const pathParts = [...prefix, node.name];\n const path = pathParts.join(\"/\");\n const binding = bindings[path];\n const value = this.resolveBinding(binding, context) ?? node.input.defaultValue;\n\n const finalValue = onResolved ? onResolved(value, node.input) : value;\n\n if (node.children.length > 0) {\n if (node.list) {\n const uniqueIndexes = this.getUniqueIndexesFromPath(path, bindings);\n\n target[node.name] = uniqueIndexes.map(index => {\n const childTarget: Record<string, any> = {};\n resolveInputsFromAst(\n node.children,\n [...pathParts.slice(0, -1), `${node.name}/${index}`],\n childTarget\n );\n return childTarget;\n });\n } else {\n const childTarget: Record<string, any> = {};\n resolveInputsFromAst(node.children, pathParts, childTarget);\n target[node.name] = childTarget;\n }\n } else if (node.list) {\n // List node with no children (e.g., slot or primitive list)\n const uniqueIndexes = this.getUniqueIndexesFromPath(path, bindings);\n\n // If binding is e.g., `leftColumn/0`, we'll have `0` in unique indexes.\n if (uniqueIndexes.length > 0) {\n target[node.name] = uniqueIndexes.map(index => {\n const binding = bindings[`${node.name}/${index}`];\n const value =\n this.resolveBinding(binding, context) ?? node.input.defaultValue;\n return onResolved ? onResolved(value, node.input) : value;\n });\n } else {\n // If binding is a simple `children`, we simply assign the resolved value.\n target[node.name] = finalValue;\n }\n } else if (finalValue !== undefined) {\n target[node.name] = finalValue;\n }\n }\n };\n\n resolveInputsFromAst(inputAst, [], resolvedElement.inputs);\n\n // Resolve styles\n const styles: DocumentElementStyleBindings = elementBindings.styles\n ? (elementBindings.styles ?? {})\n : {};\n\n const resolvedStyles: SerializableCSSStyleDeclaration = {};\n\n for (const [path, binding] of Object.entries(styles)) {\n if (binding) {\n // @ts-expect-error We're positive this is correct.\n resolvedStyles[path] = this.resolveBinding(binding, context);\n }\n }\n\n return {\n ...resolvedElement,\n styles: resolvedStyles\n };\n }\n\n private getUniqueIndexesFromPath(flatKey: string, bindings: DocumentElementBindings) {\n const pattern = new RegExp(`^${flatKey}\\\\/(\\\\d+)`);\n\n const indexes = Object.keys(bindings).reduce((acc: number[], key) => {\n const match = key.match(pattern);\n if (match) {\n acc.push(parseInt(match[1], 10));\n }\n return acc;\n }, []);\n\n return Array.from(new Set(indexes)).sort((a, b) => a - b);\n }\n\n private resolveBinding(binding: ValueBinding | undefined, context: Record<string, any>): any {\n if (typeof binding === \"undefined\") {\n return undefined;\n }\n\n if (binding.expression) {\n return this.evaluateExpression(binding.expression, context);\n }\n\n if (binding.static) {\n return binding.static;\n }\n\n return undefined;\n }\n\n private evaluateExpression(expression: string | undefined, context: Record<string, any> = {}) {\n if (!expression || expression === \"$noop\") {\n return undefined;\n }\n\n try {\n let finalExpression = expression.trim();\n\n if (finalExpression.startsWith(\"$state\")) {\n finalExpression = finalExpression.replace(/^\\$state/, \"state\");\n }\n\n finalExpression = finalExpression.replace(/\\.([0-9]+)/g, \"[$1]\");\n\n const scopedFn = new Function(...Object.keys(context), `return ${finalExpression};`);\n return scopedFn(...Object.values(context));\n } catch {\n return undefined;\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["toJS","BindingsResolver","constructor","state","resolveElement","element","elementBindings","inputAst","onResolved","repeatBindingArray","$repeat","items","resolveBinding","Array","isArray","map","item","resolveSingleInstance","undefined","resolvedElement","id","inputs","styles","context","$","bindings","resolveInputsFromAst","nodes","prefix","target","node","pathParts","name","path","join","binding","value","input","defaultValue","finalValue","children","length","list","uniqueIndexes","getUniqueIndexesFromPath","index","childTarget","slice","resolvedStyles","Object","entries","flatKey","pattern","RegExp","indexes","keys","reduce","acc","key","match","push","parseInt","from","Set","sort","a","b","expression","evaluateExpression","static","finalExpression","trim","startsWith","replace","scopedFn","Function","values"],"sources":["BindingsResolver.ts"],"sourcesContent":["import { toJS } from \"mobx\";\nimport type {\n ComponentInput,\n DocumentElement,\n DocumentElementBindings,\n DocumentElementStyleBindings,\n DocumentState,\n ResolvedElement,\n SerializableCSSStyleDeclaration,\n ValueBinding\n} from \"~/types.js\";\nimport type { InputAstNode } from \"./ComponentManifestToAstConverter.js\";\n\nexport interface OnResolved {\n (value: any, input: ComponentInput): any;\n}\n\nexport type ResolveElementParams = {\n element: DocumentElement;\n elementBindings: DocumentElementBindings;\n inputAst: InputAstNode[];\n onResolved?: OnResolved;\n};\n\nexport class BindingsResolver {\n private readonly state: DocumentState;\n\n constructor(state: DocumentState) {\n this.state = state;\n }\n\n public resolveElement({\n element,\n elementBindings,\n inputAst,\n onResolved\n }: ResolveElementParams): ResolvedElement[] {\n const repeatBindingArray = elementBindings.$repeat;\n\n if (repeatBindingArray) {\n const items = this.resolveBinding(repeatBindingArray, { state: toJS(this.state) });\n\n if (!Array.isArray(items)) {\n return [];\n }\n\n return items.map(item => {\n return this.resolveSingleInstance(\n element,\n elementBindings,\n item,\n inputAst,\n onResolved\n );\n });\n }\n\n return [\n this.resolveSingleInstance(element, elementBindings, undefined, inputAst, onResolved)\n ];\n }\n\n private resolveSingleInstance(\n element: DocumentElement,\n elementBindings: DocumentElementBindings,\n item: Record<string, any> | undefined,\n inputAst: InputAstNode[],\n onResolved?: OnResolved\n ): ResolvedElement {\n const resolvedElement: ResolvedElement = {\n id: element.id,\n inputs: {},\n styles: {}\n };\n\n const context = { state: this.state, $: item };\n const bindings = elementBindings.inputs ?? {};\n\n const resolveInputsFromAst = (\n nodes: InputAstNode[],\n prefix: string[],\n target: Record<string, any>\n ) => {\n for (const node of nodes) {\n const pathParts = [...prefix, node.name];\n const path = pathParts.join(\"/\");\n const binding = bindings[path];\n const value = this.resolveBinding(binding, context) ?? node.input.defaultValue;\n\n const finalValue = onResolved ? onResolved(value, node.input) : value;\n\n if (node.children.length > 0) {\n if (node.list) {\n const uniqueIndexes = this.getUniqueIndexesFromPath(path, bindings);\n\n target[node.name] = uniqueIndexes.map(index => {\n const childTarget: Record<string, any> = {};\n resolveInputsFromAst(\n node.children,\n [...pathParts.slice(0, -1), `${node.name}/${index}`],\n childTarget\n );\n return childTarget;\n });\n } else {\n const childTarget: Record<string, any> = {};\n resolveInputsFromAst(node.children, pathParts, childTarget);\n target[node.name] = childTarget;\n }\n } else if (node.list) {\n // List node with no children (e.g., slot or primitive list)\n const uniqueIndexes = this.getUniqueIndexesFromPath(path, bindings);\n\n // If binding is e.g., `leftColumn/0`, we'll have `0` in unique indexes.\n if (uniqueIndexes.length > 0) {\n target[node.name] = uniqueIndexes.map(index => {\n const binding = bindings[`${node.name}/${index}`];\n const value =\n this.resolveBinding(binding, context) ?? node.input.defaultValue;\n return onResolved ? onResolved(value, node.input) : value;\n });\n } else {\n // If binding is a simple `children`, we simply assign the resolved value.\n target[node.name] = finalValue;\n }\n } else if (finalValue !== undefined) {\n target[node.name] = finalValue;\n }\n }\n };\n\n resolveInputsFromAst(inputAst, [], resolvedElement.inputs);\n\n // Resolve styles\n const styles: DocumentElementStyleBindings = elementBindings.styles\n ? (elementBindings.styles ?? {})\n : {};\n\n const resolvedStyles: SerializableCSSStyleDeclaration = {};\n\n for (const [path, binding] of Object.entries(styles)) {\n if (binding) {\n // @ts-expect-error We're positive this is correct.\n resolvedStyles[path] = this.resolveBinding(binding, context);\n }\n }\n\n return {\n ...resolvedElement,\n styles: resolvedStyles\n };\n }\n\n private getUniqueIndexesFromPath(flatKey: string, bindings: DocumentElementBindings) {\n const pattern = new RegExp(`^${flatKey}\\\\/(\\\\d+)`);\n\n const indexes = Object.keys(bindings).reduce((acc: number[], key) => {\n const match = key.match(pattern);\n if (match) {\n acc.push(parseInt(match[1], 10));\n }\n return acc;\n }, []);\n\n return Array.from(new Set(indexes)).sort((a, b) => a - b);\n }\n\n private resolveBinding(binding: ValueBinding | undefined, context: Record<string, any>): any {\n if (typeof binding === \"undefined\") {\n return undefined;\n }\n\n if (binding.expression) {\n return this.evaluateExpression(binding.expression, context);\n }\n\n return binding.static;\n }\n\n private evaluateExpression(expression: string | undefined, context: Record<string, any> = {}) {\n if (!expression || expression === \"$noop\") {\n return undefined;\n }\n\n try {\n let finalExpression = expression.trim();\n\n if (finalExpression.startsWith(\"$state\")) {\n finalExpression = finalExpression.replace(/^\\$state/, \"state\");\n }\n\n finalExpression = finalExpression.replace(/\\.([0-9]+)/g, \"[$1]\");\n\n const scopedFn = new Function(...Object.keys(context), `return ${finalExpression};`);\n return scopedFn(...Object.values(context));\n } catch {\n return undefined;\n }\n }\n}\n"],"mappings":"AAAA,SAASA,IAAI,QAAQ,MAAM;AAwB3B,OAAO,MAAMC,gBAAgB,CAAC;EAG1BC,WAAWA,CAACC,KAAoB,EAAE;IAC9B,IAAI,CAACA,KAAK,GAAGA,KAAK;EACtB;EAEOC,cAAcA,CAAC;IAClBC,OAAO;IACPC,eAAe;IACfC,QAAQ;IACRC;EACkB,CAAC,EAAqB;IACxC,MAAMC,kBAAkB,GAAGH,eAAe,CAACI,OAAO;IAElD,IAAID,kBAAkB,EAAE;MACpB,MAAME,KAAK,GAAG,IAAI,CAACC,cAAc,CAACH,kBAAkB,EAAE;QAAEN,KAAK,EAAEH,IAAI,CAAC,IAAI,CAACG,KAAK;MAAE,CAAC,CAAC;MAElF,IAAI,CAACU,KAAK,CAACC,OAAO,CAACH,KAAK,CAAC,EAAE;QACvB,OAAO,EAAE;MACb;MAEA,OAAOA,KAAK,CAACI,GAAG,CAACC,IAAI,IAAI;QACrB,OAAO,IAAI,CAACC,qBAAqB,CAC7BZ,OAAO,EACPC,eAAe,EACfU,IAAI,EACJT,QAAQ,EACRC,UACJ,CAAC;MACL,CAAC,CAAC;IACN;IAEA,OAAO,CACH,IAAI,CAACS,qBAAqB,CAACZ,OAAO,EAAEC,eAAe,EAAEY,SAAS,EAAEX,QAAQ,EAAEC,UAAU,CAAC,CACxF;EACL;EAEQS,qBAAqBA,CACzBZ,OAAwB,EACxBC,eAAwC,EACxCU,IAAqC,EACrCT,QAAwB,EACxBC,UAAuB,EACR;IACf,MAAMW,eAAgC,GAAG;MACrCC,EAAE,EAAEf,OAAO,CAACe,EAAE;MACdC,MAAM,EAAE,CAAC,CAAC;MACVC,MAAM,EAAE,CAAC;IACb,CAAC;IAED,MAAMC,OAAO,GAAG;MAAEpB,KAAK,EAAE,IAAI,CAACA,KAAK;MAAEqB,CAAC,EAAER;IAAK,CAAC;IAC9C,MAAMS,QAAQ,GAAGnB,eAAe,CAACe,MAAM,IAAI,CAAC,CAAC;IAE7C,MAAMK,oBAAoB,GAAGA,CACzBC,KAAqB,EACrBC,MAAgB,EAChBC,MAA2B,KAC1B;MACD,KAAK,MAAMC,IAAI,IAAIH,KAAK,EAAE;QACtB,MAAMI,SAAS,GAAG,CAAC,GAAGH,MAAM,EAAEE,IAAI,CAACE,IAAI,CAAC;QACxC,MAAMC,IAAI,GAAGF,SAAS,CAACG,IAAI,CAAC,GAAG,CAAC;QAChC,MAAMC,OAAO,GAAGV,QAAQ,CAACQ,IAAI,CAAC;QAC9B,MAAMG,KAAK,GAAG,IAAI,CAACxB,cAAc,CAACuB,OAAO,EAAEZ,OAAO,CAAC,IAAIO,IAAI,CAACO,KAAK,CAACC,YAAY;QAE9E,MAAMC,UAAU,GAAG/B,UAAU,GAAGA,UAAU,CAAC4B,KAAK,EAAEN,IAAI,CAACO,KAAK,CAAC,GAAGD,KAAK;QAErE,IAAIN,IAAI,CAACU,QAAQ,CAACC,MAAM,GAAG,CAAC,EAAE;UAC1B,IAAIX,IAAI,CAACY,IAAI,EAAE;YACX,MAAMC,aAAa,GAAG,IAAI,CAACC,wBAAwB,CAACX,IAAI,EAAER,QAAQ,CAAC;YAEnEI,MAAM,CAACC,IAAI,CAACE,IAAI,CAAC,GAAGW,aAAa,CAAC5B,GAAG,CAAC8B,KAAK,IAAI;cAC3C,MAAMC,WAAgC,GAAG,CAAC,CAAC;cAC3CpB,oBAAoB,CAChBI,IAAI,CAACU,QAAQ,EACb,CAAC,GAAGT,SAAS,CAACgB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAGjB,IAAI,CAACE,IAAI,IAAIa,KAAK,EAAE,CAAC,EACpDC,WACJ,CAAC;cACD,OAAOA,WAAW;YACtB,CAAC,CAAC;UACN,CAAC,MAAM;YACH,MAAMA,WAAgC,GAAG,CAAC,CAAC;YAC3CpB,oBAAoB,CAACI,IAAI,CAACU,QAAQ,EAAET,SAAS,EAAEe,WAAW,CAAC;YAC3DjB,MAAM,CAACC,IAAI,CAACE,IAAI,CAAC,GAAGc,WAAW;UACnC;QACJ,CAAC,MAAM,IAAIhB,IAAI,CAACY,IAAI,EAAE;UAClB;UACA,MAAMC,aAAa,GAAG,IAAI,CAACC,wBAAwB,CAACX,IAAI,EAAER,QAAQ,CAAC;;UAEnE;UACA,IAAIkB,aAAa,CAACF,MAAM,GAAG,CAAC,EAAE;YAC1BZ,MAAM,CAACC,IAAI,CAACE,IAAI,CAAC,GAAGW,aAAa,CAAC5B,GAAG,CAAC8B,KAAK,IAAI;cAC3C,MAAMV,OAAO,GAAGV,QAAQ,CAAC,GAAGK,IAAI,CAACE,IAAI,IAAIa,KAAK,EAAE,CAAC;cACjD,MAAMT,KAAK,GACP,IAAI,CAACxB,cAAc,CAACuB,OAAO,EAAEZ,OAAO,CAAC,IAAIO,IAAI,CAACO,KAAK,CAACC,YAAY;cACpE,OAAO9B,UAAU,GAAGA,UAAU,CAAC4B,KAAK,EAAEN,IAAI,CAACO,KAAK,CAAC,GAAGD,KAAK;YAC7D,CAAC,CAAC;UACN,CAAC,MAAM;YACH;YACAP,MAAM,CAACC,IAAI,CAACE,IAAI,CAAC,GAAGO,UAAU;UAClC;QACJ,CAAC,MAAM,IAAIA,UAAU,KAAKrB,SAAS,EAAE;UACjCW,MAAM,CAACC,IAAI,CAACE,IAAI,CAAC,GAAGO,UAAU;QAClC;MACJ;IACJ,CAAC;IAEDb,oBAAoB,CAACnB,QAAQ,EAAE,EAAE,EAAEY,eAAe,CAACE,MAAM,CAAC;;IAE1D;IACA,MAAMC,MAAoC,GAAGhB,eAAe,CAACgB,MAAM,GAC5DhB,eAAe,CAACgB,MAAM,IAAI,CAAC,CAAC,GAC7B,CAAC,CAAC;IAER,MAAM0B,cAA+C,GAAG,CAAC,CAAC;IAE1D,KAAK,MAAM,CAACf,IAAI,EAAEE,OAAO,CAAC,IAAIc,MAAM,CAACC,OAAO,CAAC5B,MAAM,CAAC,EAAE;MAClD,IAAIa,OAAO,EAAE;QACT;QACAa,cAAc,CAACf,IAAI,CAAC,GAAG,IAAI,CAACrB,cAAc,CAACuB,OAAO,EAAEZ,OAAO,CAAC;MAChE;IACJ;IAEA,OAAO;MACH,GAAGJ,eAAe;MAClBG,MAAM,EAAE0B;IACZ,CAAC;EACL;EAEQJ,wBAAwBA,CAACO,OAAe,EAAE1B,QAAiC,EAAE;IACjF,MAAM2B,OAAO,GAAG,IAAIC,MAAM,CAAC,IAAIF,OAAO,WAAW,CAAC;IAElD,MAAMG,OAAO,GAAGL,MAAM,CAACM,IAAI,CAAC9B,QAAQ,CAAC,CAAC+B,MAAM,CAAC,CAACC,GAAa,EAAEC,GAAG,KAAK;MACjE,MAAMC,KAAK,GAAGD,GAAG,CAACC,KAAK,CAACP,OAAO,CAAC;MAChC,IAAIO,KAAK,EAAE;QACPF,GAAG,CAACG,IAAI,CAACC,QAAQ,CAACF,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;MACpC;MACA,OAAOF,GAAG;IACd,CAAC,EAAE,EAAE,CAAC;IAEN,OAAO5C,KAAK,CAACiD,IAAI,CAAC,IAAIC,GAAG,CAACT,OAAO,CAAC,CAAC,CAACU,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAKD,CAAC,GAAGC,CAAC,CAAC;EAC7D;EAEQtD,cAAcA,CAACuB,OAAiC,EAAEZ,OAA4B,EAAO;IACzF,IAAI,OAAOY,OAAO,KAAK,WAAW,EAAE;MAChC,OAAOjB,SAAS;IACpB;IAEA,IAAIiB,OAAO,CAACgC,UAAU,EAAE;MACpB,OAAO,IAAI,CAACC,kBAAkB,CAACjC,OAAO,CAACgC,UAAU,EAAE5C,OAAO,CAAC;IAC/D;IAEA,OAAOY,OAAO,CAACkC,MAAM;EACzB;EAEQD,kBAAkBA,CAACD,UAA8B,EAAE5C,OAA4B,GAAG,CAAC,CAAC,EAAE;IAC1F,IAAI,CAAC4C,UAAU,IAAIA,UAAU,KAAK,OAAO,EAAE;MACvC,OAAOjD,SAAS;IACpB;IAEA,IAAI;MACA,IAAIoD,eAAe,GAAGH,UAAU,CAACI,IAAI,CAAC,CAAC;MAEvC,IAAID,eAAe,CAACE,UAAU,CAAC,QAAQ,CAAC,EAAE;QACtCF,eAAe,GAAGA,eAAe,CAACG,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC;MAClE;MAEAH,eAAe,GAAGA,eAAe,CAACG,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC;MAEhE,MAAMC,QAAQ,GAAG,IAAIC,QAAQ,CAAC,GAAG1B,MAAM,CAACM,IAAI,CAAChC,OAAO,CAAC,EAAE,UAAU+C,eAAe,GAAG,CAAC;MACpF,OAAOI,QAAQ,CAAC,GAAGzB,MAAM,CAAC2B,MAAM,CAACrD,OAAO,CAAC,CAAC;IAC9C,CAAC,CAAC,MAAM;MACJ,OAAOL,SAAS;IACpB;EACJ;AACJ","ignoreList":[]}
|
package/ComponentRegistry.js
CHANGED
|
@@ -1,8 +1,32 @@
|
|
|
1
|
+
import { functionConverter } from "./FunctionConverter.js";
|
|
1
2
|
export class ComponentRegistry {
|
|
2
3
|
registry = new Map();
|
|
3
4
|
listeners = new Set();
|
|
4
5
|
register(component) {
|
|
5
6
|
const name = component.manifest.name;
|
|
7
|
+
// Normalize optional fields so downstream code never sees undefined.
|
|
8
|
+
component.manifest.tags = component.manifest.tags ?? [];
|
|
9
|
+
// Serialize constraint and handler functions for cross-boundary transport
|
|
10
|
+
if (component.manifest.constraints) {
|
|
11
|
+
// @ts-expect-error Serialized form is string[], but type expects function[].
|
|
12
|
+
component.manifest.constraints = component.manifest.constraints.map(fn => functionConverter.serialize(fn));
|
|
13
|
+
}
|
|
14
|
+
if (component.manifest.descendantConstraints) {
|
|
15
|
+
// @ts-expect-error Serialized form is string[], but type expects function[].
|
|
16
|
+
component.manifest.descendantConstraints = component.manifest.descendantConstraints.map(fn => functionConverter.serialize(fn));
|
|
17
|
+
}
|
|
18
|
+
if (component.manifest.canDelete && typeof component.manifest.canDelete === "function") {
|
|
19
|
+
// @ts-expect-error Serialized form is a string, but type expects a function.
|
|
20
|
+
component.manifest.canDelete = functionConverter.serialize(component.manifest.canDelete);
|
|
21
|
+
}
|
|
22
|
+
if (component.manifest.onChange) {
|
|
23
|
+
// @ts-expect-error Serialized form is a string (or string[]), but type expects a function.
|
|
24
|
+
component.manifest.onChange = serializeHandlers(component.manifest.onChange);
|
|
25
|
+
}
|
|
26
|
+
if (component.manifest.onDescendantChange) {
|
|
27
|
+
// @ts-expect-error Serialized form is a string (or string[]), but type expects a function.
|
|
28
|
+
component.manifest.onDescendantChange = serializeHandlers(component.manifest.onDescendantChange);
|
|
29
|
+
}
|
|
6
30
|
this.registry.set(name, component);
|
|
7
31
|
// notify subscribers
|
|
8
32
|
this.listeners.forEach(fn => fn({
|
|
@@ -20,6 +44,12 @@ export class ComponentRegistry {
|
|
|
20
44
|
return () => this.listeners.delete(fn);
|
|
21
45
|
}
|
|
22
46
|
}
|
|
47
|
+
function serializeHandlers(handler) {
|
|
48
|
+
if (Array.isArray(handler)) {
|
|
49
|
+
return handler.map(h => functionConverter.serialize(h));
|
|
50
|
+
}
|
|
51
|
+
return functionConverter.serialize(handler);
|
|
52
|
+
}
|
|
23
53
|
export const componentRegistry = new ComponentRegistry();
|
|
24
54
|
|
|
25
55
|
//# sourceMappingURL=ComponentRegistry.js.map
|
package/ComponentRegistry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ComponentRegistry","registry","Map","listeners","Set","register","component","name","manifest","
|
|
1
|
+
{"version":3,"names":["functionConverter","ComponentRegistry","registry","Map","listeners","Set","register","component","name","manifest","tags","constraints","map","fn","serialize","descendantConstraints","canDelete","onChange","serializeHandlers","onDescendantChange","set","forEach","get","onRegister","add","delete","handler","Array","isArray","h","componentRegistry"],"sources":["ComponentRegistry.ts"],"sourcesContent":["import type { Component } from \"~/types.js\";\nimport { functionConverter } from \"~/FunctionConverter.js\";\n\ntype Registration = { name: string; component: Component };\n\nexport class ComponentRegistry {\n private registry = new Map<string, Component>();\n private listeners = new Set<(reg: Registration) => void>();\n\n public register(component: Component) {\n const name = component.manifest.name;\n // Normalize optional fields so downstream code never sees undefined.\n component.manifest.tags = component.manifest.tags ?? [];\n // Serialize constraint and handler functions for cross-boundary transport\n if (component.manifest.constraints) {\n // @ts-expect-error Serialized form is string[], but type expects function[].\n component.manifest.constraints = component.manifest.constraints.map(fn =>\n functionConverter.serialize(fn)\n );\n }\n if (component.manifest.descendantConstraints) {\n // @ts-expect-error Serialized form is string[], but type expects function[].\n component.manifest.descendantConstraints = component.manifest.descendantConstraints.map(\n fn => functionConverter.serialize(fn)\n );\n }\n if (component.manifest.canDelete && typeof component.manifest.canDelete === \"function\") {\n // @ts-expect-error Serialized form is a string, but type expects a function.\n component.manifest.canDelete = functionConverter.serialize(\n component.manifest.canDelete\n );\n }\n if (component.manifest.onChange) {\n // @ts-expect-error Serialized form is a string (or string[]), but type expects a function.\n component.manifest.onChange = serializeHandlers(component.manifest.onChange);\n }\n if (component.manifest.onDescendantChange) {\n // @ts-expect-error Serialized form is a string (or string[]), but type expects a function.\n component.manifest.onDescendantChange = serializeHandlers(\n component.manifest.onDescendantChange\n );\n }\n this.registry.set(name, component);\n // notify subscribers\n this.listeners.forEach(fn => fn({ name, component }));\n }\n\n public get(name: string) {\n return this.registry.get(name);\n }\n\n /** subscribe to *all* registrations */\n public onRegister(fn: (reg: Registration) => void) {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n}\n\nfunction serializeHandlers(\n handler: ((...args: any[]) => any) | ((...args: any[]) => any)[]\n): string | string[] {\n if (Array.isArray(handler)) {\n return handler.map(h => functionConverter.serialize(h));\n }\n return functionConverter.serialize(handler);\n}\n\nexport const componentRegistry = new ComponentRegistry();\n"],"mappings":"AACA,SAASA,iBAAiB;AAI1B,OAAO,MAAMC,iBAAiB,CAAC;EACnBC,QAAQ,GAAG,IAAIC,GAAG,CAAoB,CAAC;EACvCC,SAAS,GAAG,IAAIC,GAAG,CAA8B,CAAC;EAEnDC,QAAQA,CAACC,SAAoB,EAAE;IAClC,MAAMC,IAAI,GAAGD,SAAS,CAACE,QAAQ,CAACD,IAAI;IACpC;IACAD,SAAS,CAACE,QAAQ,CAACC,IAAI,GAAGH,SAAS,CAACE,QAAQ,CAACC,IAAI,IAAI,EAAE;IACvD;IACA,IAAIH,SAAS,CAACE,QAAQ,CAACE,WAAW,EAAE;MAChC;MACAJ,SAAS,CAACE,QAAQ,CAACE,WAAW,GAAGJ,SAAS,CAACE,QAAQ,CAACE,WAAW,CAACC,GAAG,CAACC,EAAE,IAClEb,iBAAiB,CAACc,SAAS,CAACD,EAAE,CAClC,CAAC;IACL;IACA,IAAIN,SAAS,CAACE,QAAQ,CAACM,qBAAqB,EAAE;MAC1C;MACAR,SAAS,CAACE,QAAQ,CAACM,qBAAqB,GAAGR,SAAS,CAACE,QAAQ,CAACM,qBAAqB,CAACH,GAAG,CACnFC,EAAE,IAAIb,iBAAiB,CAACc,SAAS,CAACD,EAAE,CACxC,CAAC;IACL;IACA,IAAIN,SAAS,CAACE,QAAQ,CAACO,SAAS,IAAI,OAAOT,SAAS,CAACE,QAAQ,CAACO,SAAS,KAAK,UAAU,EAAE;MACpF;MACAT,SAAS,CAACE,QAAQ,CAACO,SAAS,GAAGhB,iBAAiB,CAACc,SAAS,CACtDP,SAAS,CAACE,QAAQ,CAACO,SACvB,CAAC;IACL;IACA,IAAIT,SAAS,CAACE,QAAQ,CAACQ,QAAQ,EAAE;MAC7B;MACAV,SAAS,CAACE,QAAQ,CAACQ,QAAQ,GAAGC,iBAAiB,CAACX,SAAS,CAACE,QAAQ,CAACQ,QAAQ,CAAC;IAChF;IACA,IAAIV,SAAS,CAACE,QAAQ,CAACU,kBAAkB,EAAE;MACvC;MACAZ,SAAS,CAACE,QAAQ,CAACU,kBAAkB,GAAGD,iBAAiB,CACrDX,SAAS,CAACE,QAAQ,CAACU,kBACvB,CAAC;IACL;IACA,IAAI,CAACjB,QAAQ,CAACkB,GAAG,CAACZ,IAAI,EAAED,SAAS,CAAC;IAClC;IACA,IAAI,CAACH,SAAS,CAACiB,OAAO,CAACR,EAAE,IAAIA,EAAE,CAAC;MAAEL,IAAI;MAAED;IAAU,CAAC,CAAC,CAAC;EACzD;EAEOe,GAAGA,CAACd,IAAY,EAAE;IACrB,OAAO,IAAI,CAACN,QAAQ,CAACoB,GAAG,CAACd,IAAI,CAAC;EAClC;;EAEA;EACOe,UAAUA,CAACV,EAA+B,EAAE;IAC/C,IAAI,CAACT,SAAS,CAACoB,GAAG,CAACX,EAAE,CAAC;IACtB,OAAO,MAAM,IAAI,CAACT,SAAS,CAACqB,MAAM,CAACZ,EAAE,CAAC;EAC1C;AACJ;AAEA,SAASK,iBAAiBA,CACtBQ,OAAgE,EAC/C;EACjB,IAAIC,KAAK,CAACC,OAAO,CAACF,OAAO,CAAC,EAAE;IACxB,OAAOA,OAAO,CAACd,GAAG,CAACiB,CAAC,IAAI7B,iBAAiB,CAACc,SAAS,CAACe,CAAC,CAAC,CAAC;EAC3D;EACA,OAAO7B,iBAAiB,CAACc,SAAS,CAACY,OAAO,CAAC;AAC/C;AAEA,OAAO,MAAMI,iBAAiB,GAAG,IAAI7B,iBAAiB,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ComponentManifest, ConstraintElementContext, Document, DocumentElement } from "./types.js";
|
|
2
|
+
export type ConstraintViolation = {
|
|
3
|
+
message: string;
|
|
4
|
+
};
|
|
5
|
+
export type ConstraintResult = {
|
|
6
|
+
allowed: boolean;
|
|
7
|
+
violation?: ConstraintViolation;
|
|
8
|
+
};
|
|
9
|
+
export interface EvaluateConstraintsParams {
|
|
10
|
+
/** The component being placed */
|
|
11
|
+
componentName: string;
|
|
12
|
+
/** Target parent element ID */
|
|
13
|
+
parentId: string;
|
|
14
|
+
/** Target slot */
|
|
15
|
+
slot: string;
|
|
16
|
+
/** The document */
|
|
17
|
+
document: Document;
|
|
18
|
+
/** All registered component manifests */
|
|
19
|
+
components: Record<string, ComponentManifest>;
|
|
20
|
+
}
|
|
21
|
+
export declare function buildElementContext(element: DocumentElement, components: Record<string, ComponentManifest>, document: Document): ConstraintElementContext | undefined;
|
|
22
|
+
export interface InternalAncestor {
|
|
23
|
+
element: DocumentElement;
|
|
24
|
+
manifest: ComponentManifest;
|
|
25
|
+
}
|
|
26
|
+
export declare function buildAncestors(parentElement: DocumentElement, components: Record<string, ComponentManifest>, document: Document): InternalAncestor[];
|
|
27
|
+
export declare function evaluateConstraints(params: EvaluateConstraintsParams): ConstraintResult;
|
|
28
|
+
export interface EvaluateDeleteConstraintParams {
|
|
29
|
+
/** The element being deleted */
|
|
30
|
+
elementId: string;
|
|
31
|
+
/** The document */
|
|
32
|
+
document: Document;
|
|
33
|
+
/** All registered component manifests */
|
|
34
|
+
components: Record<string, ComponentManifest>;
|
|
35
|
+
}
|
|
36
|
+
export declare function evaluateDeleteConstraint(params: EvaluateDeleteConstraintParams): ConstraintResult;
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
class ConstraintBlockError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
function block(message) {
|
|
7
|
+
throw new ConstraintBlockError(message);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Build a regex pattern from a slot path, replacing the numeric index with \d+.
|
|
11
|
+
* E.g., "steps/2/step" → /^steps\/\d+\/step$/
|
|
12
|
+
* Returns undefined if the slot has no index segment.
|
|
13
|
+
*/
|
|
14
|
+
function buildSlotPattern(slot) {
|
|
15
|
+
const match = slot.match(/\/(\d+)\//);
|
|
16
|
+
if (!match) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
return new RegExp("^" + slot.replace(/\/\d+\//, "/\\d+/") + "$");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Find the actual index and sibling count for an element in its parent's bindings.
|
|
24
|
+
* Instead of trusting element.parent.slot (which may be stale after reordering),
|
|
25
|
+
* we scan the parent's binding keys to find which slot holds this element's ID.
|
|
26
|
+
* Returns { index, count } or undefined if not in a list slot.
|
|
27
|
+
*/
|
|
28
|
+
function findChildPosition(element, document) {
|
|
29
|
+
if (!element.parent?.id || !element.parent.slot) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const inputs = document.bindings[element.parent.id]?.inputs;
|
|
33
|
+
if (!inputs) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Try direct list slot format: binding key = slot name, static = array of IDs.
|
|
38
|
+
// Only when the slot path itself is NOT an indexed sub-key (e.g., "steps", not "steps/0/step").
|
|
39
|
+
const slotName = element.parent.slot;
|
|
40
|
+
if (!/\/\d+\//.test(slotName)) {
|
|
41
|
+
const directBinding = inputs[slotName];
|
|
42
|
+
if (directBinding && Array.isArray(directBinding.static)) {
|
|
43
|
+
const index = directBinding.static.indexOf(element.id);
|
|
44
|
+
if (index !== -1) {
|
|
45
|
+
return {
|
|
46
|
+
index,
|
|
47
|
+
count: directBinding.static.length
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Fall back to indexed sub-key format: steps/0/step, steps/1/step, etc.
|
|
54
|
+
const pattern = buildSlotPattern(slotName);
|
|
55
|
+
if (!pattern) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const siblingKeys = [];
|
|
59
|
+
for (const key in inputs) {
|
|
60
|
+
if (pattern.test(key)) {
|
|
61
|
+
const m = key.match(/\/(\d+)\//);
|
|
62
|
+
if (m) {
|
|
63
|
+
siblingKeys.push({
|
|
64
|
+
key,
|
|
65
|
+
idx: parseInt(m[1], 10)
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
siblingKeys.sort((a, b) => a.idx - b.idx);
|
|
71
|
+
const position = siblingKeys.findIndex(({
|
|
72
|
+
key
|
|
73
|
+
}) => {
|
|
74
|
+
const val = inputs[key]?.static;
|
|
75
|
+
if (Array.isArray(val)) {
|
|
76
|
+
return val.includes(element.id);
|
|
77
|
+
}
|
|
78
|
+
return val === element.id;
|
|
79
|
+
});
|
|
80
|
+
if (position === -1) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
index: position,
|
|
85
|
+
count: siblingKeys.length
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export function buildElementContext(element, components, document) {
|
|
89
|
+
const manifest = components[element.component.name];
|
|
90
|
+
if (!manifest) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
name: element.component.name,
|
|
95
|
+
tags: manifest.tags ?? [],
|
|
96
|
+
getParent() {
|
|
97
|
+
if (!element.parent?.id) {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
const parentEl = document.elements[element.parent.id];
|
|
101
|
+
if (!parentEl) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
return buildElementContext(parentEl, components, document);
|
|
105
|
+
},
|
|
106
|
+
childIndex() {
|
|
107
|
+
const pos = findChildPosition(element, document);
|
|
108
|
+
return pos ? pos.index : -1;
|
|
109
|
+
},
|
|
110
|
+
childCount() {
|
|
111
|
+
const pos = findChildPosition(element, document);
|
|
112
|
+
return pos ? pos.count : -1;
|
|
113
|
+
},
|
|
114
|
+
isLastChild() {
|
|
115
|
+
const pos = findChildPosition(element, document);
|
|
116
|
+
return pos !== undefined && pos.index === pos.count - 1;
|
|
117
|
+
},
|
|
118
|
+
isFirstChild() {
|
|
119
|
+
const pos = findChildPosition(element, document);
|
|
120
|
+
return pos !== undefined && pos.index === 0;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export function buildAncestors(parentElement, components, document) {
|
|
125
|
+
const ancestors = [];
|
|
126
|
+
let current = parentElement;
|
|
127
|
+
while (current) {
|
|
128
|
+
const manifest = components[current.component.name];
|
|
129
|
+
if (manifest) {
|
|
130
|
+
ancestors.push({
|
|
131
|
+
element: current,
|
|
132
|
+
manifest
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (current.parent?.id) {
|
|
136
|
+
current = document.elements[current.parent.id];
|
|
137
|
+
} else {
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return ancestors;
|
|
142
|
+
}
|
|
143
|
+
function countInstances(document, componentName) {
|
|
144
|
+
let count = 0;
|
|
145
|
+
for (const id in document.elements) {
|
|
146
|
+
if (document.elements[id].component.name === componentName) {
|
|
147
|
+
count++;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return count;
|
|
151
|
+
}
|
|
152
|
+
function hasDescendantWithTag(document, components, elementId, tag) {
|
|
153
|
+
for (const id in document.elements) {
|
|
154
|
+
const el = document.elements[id];
|
|
155
|
+
if (id === elementId) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
// Walk up parent chain to see if elementId is an ancestor.
|
|
159
|
+
let current = el.parent?.id ? document.elements[el.parent.id] : undefined;
|
|
160
|
+
let isDescendant = false;
|
|
161
|
+
while (current) {
|
|
162
|
+
if (current.id === elementId) {
|
|
163
|
+
isDescendant = true;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
current = current.parent?.id ? document.elements[current.parent.id] : undefined;
|
|
167
|
+
}
|
|
168
|
+
if (!isDescendant) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const elManifest = components[el.component.name];
|
|
172
|
+
if (elManifest?.tags?.includes(tag)) {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
export function evaluateConstraints(params) {
|
|
179
|
+
const {
|
|
180
|
+
componentName,
|
|
181
|
+
parentId,
|
|
182
|
+
slot,
|
|
183
|
+
document,
|
|
184
|
+
components
|
|
185
|
+
} = params;
|
|
186
|
+
const componentManifest = components[componentName];
|
|
187
|
+
if (!componentManifest) {
|
|
188
|
+
return {
|
|
189
|
+
allowed: true
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const parentElement = document.elements[parentId];
|
|
193
|
+
if (!parentElement) {
|
|
194
|
+
return {
|
|
195
|
+
allowed: true
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const parentCtx = buildElementContext(parentElement, components, document);
|
|
199
|
+
if (!parentCtx) {
|
|
200
|
+
return {
|
|
201
|
+
allowed: true
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const ancestors = buildAncestors(parentElement, components, document);
|
|
205
|
+
const parentInputs = document.bindings[parentElement.id]?.inputs ?? {};
|
|
206
|
+
const ctx = {
|
|
207
|
+
component: {
|
|
208
|
+
name: componentManifest.name,
|
|
209
|
+
tags: componentManifest.tags ?? [],
|
|
210
|
+
// During placement, the element doesn't exist yet — position is unknown.
|
|
211
|
+
getParent: () => parentCtx,
|
|
212
|
+
childIndex: () => -1,
|
|
213
|
+
childCount: () => -1,
|
|
214
|
+
isLastChild: () => false,
|
|
215
|
+
isFirstChild: () => false
|
|
216
|
+
},
|
|
217
|
+
parent: parentCtx,
|
|
218
|
+
slot,
|
|
219
|
+
isChildOf: name => parentElement.component.name === name,
|
|
220
|
+
isDescendantOf: name => ancestors.some(a => a.manifest.name === name),
|
|
221
|
+
getAncestor: name => {
|
|
222
|
+
const found = ancestors.find(a => a.manifest.name === name);
|
|
223
|
+
return found ? buildElementContext(found.element, components, document) : undefined;
|
|
224
|
+
},
|
|
225
|
+
hasTag: tag => componentManifest.tags?.includes(tag) ?? false,
|
|
226
|
+
slotChildCount: () => {
|
|
227
|
+
const items = parentInputs[slot]?.static;
|
|
228
|
+
return Array.isArray(items) ? items.length : 0;
|
|
229
|
+
},
|
|
230
|
+
countInstances: name => countInstances(document, name),
|
|
231
|
+
// Element doesn't exist yet during placement — no descendants or inputs to check.
|
|
232
|
+
hasDescendantWithTag: () => false,
|
|
233
|
+
getAncestorInputs: () => undefined,
|
|
234
|
+
getElementInputs: () => ({}),
|
|
235
|
+
log: (...args) => console.log(...args),
|
|
236
|
+
block
|
|
237
|
+
};
|
|
238
|
+
const runConstraint = (constraint, fallbackMessage) => {
|
|
239
|
+
try {
|
|
240
|
+
constraint(ctx);
|
|
241
|
+
} catch (err) {
|
|
242
|
+
if (err instanceof ConstraintBlockError) {
|
|
243
|
+
return {
|
|
244
|
+
message: err.message
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
message: err instanceof Error && err.message ? err.message : fallbackMessage
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
return undefined;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// Evaluate the placed component's own constraints.
|
|
255
|
+
if (componentManifest.constraints) {
|
|
256
|
+
for (const constraint of componentManifest.constraints) {
|
|
257
|
+
const violation = runConstraint(constraint, `Cannot place ${componentManifest.label} here.`);
|
|
258
|
+
if (violation) {
|
|
259
|
+
return {
|
|
260
|
+
allowed: false,
|
|
261
|
+
violation
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Evaluate descendantConstraints from all ancestors (including direct parent).
|
|
268
|
+
for (const ancestor of ancestors) {
|
|
269
|
+
if (ancestor.manifest.descendantConstraints) {
|
|
270
|
+
for (const constraint of ancestor.manifest.descendantConstraints) {
|
|
271
|
+
const violation = runConstraint(constraint, `Cannot place ${componentName} inside ${ancestor.manifest.label}.`);
|
|
272
|
+
if (violation) {
|
|
273
|
+
return {
|
|
274
|
+
allowed: false,
|
|
275
|
+
violation
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return {
|
|
282
|
+
allowed: true
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
export function evaluateDeleteConstraint(params) {
|
|
286
|
+
const {
|
|
287
|
+
elementId,
|
|
288
|
+
document,
|
|
289
|
+
components
|
|
290
|
+
} = params;
|
|
291
|
+
const element = document.elements[elementId];
|
|
292
|
+
if (!element) {
|
|
293
|
+
return {
|
|
294
|
+
allowed: true
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
const manifest = components[element.component.name];
|
|
298
|
+
if (!manifest) {
|
|
299
|
+
return {
|
|
300
|
+
allowed: true
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
const {
|
|
304
|
+
canDelete
|
|
305
|
+
} = manifest;
|
|
306
|
+
|
|
307
|
+
// undefined or true → allowed
|
|
308
|
+
if (canDelete === undefined || canDelete === true) {
|
|
309
|
+
return {
|
|
310
|
+
allowed: true
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// false → blocked
|
|
315
|
+
if (canDelete === false) {
|
|
316
|
+
return {
|
|
317
|
+
allowed: false,
|
|
318
|
+
violation: {
|
|
319
|
+
message: `${manifest.label} cannot be deleted.`
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// ComponentConstraint → evaluate dynamically
|
|
325
|
+
const parentElement = element.parent?.id ? document.elements[element.parent.id] : undefined;
|
|
326
|
+
const parentCtx = parentElement ? buildElementContext(parentElement, components, document) : undefined;
|
|
327
|
+
const ancestors = parentElement ? buildAncestors(parentElement, components, document) : [];
|
|
328
|
+
const parentInputs = parentElement ? document.bindings[parentElement.id]?.inputs ?? {} : {};
|
|
329
|
+
const slot = element.parent?.slot ?? "";
|
|
330
|
+
const elementCtx = buildElementContext(element, components, document);
|
|
331
|
+
const ctx = {
|
|
332
|
+
component: elementCtx,
|
|
333
|
+
parent: parentCtx ?? {
|
|
334
|
+
name: "",
|
|
335
|
+
tags: [],
|
|
336
|
+
getParent: () => undefined,
|
|
337
|
+
childIndex: () => -1,
|
|
338
|
+
childCount: () => -1,
|
|
339
|
+
isLastChild: () => false,
|
|
340
|
+
isFirstChild: () => false
|
|
341
|
+
},
|
|
342
|
+
slot,
|
|
343
|
+
isChildOf: name => parentElement?.component.name === name,
|
|
344
|
+
isDescendantOf: name => ancestors.some(a => a.manifest.name === name),
|
|
345
|
+
getAncestor: name => {
|
|
346
|
+
const found = ancestors.find(a => a.manifest.name === name);
|
|
347
|
+
return found ? buildElementContext(found.element, components, document) : undefined;
|
|
348
|
+
},
|
|
349
|
+
hasTag: tag => manifest.tags?.includes(tag) ?? false,
|
|
350
|
+
slotChildCount: () => {
|
|
351
|
+
const items = parentInputs[slot]?.static;
|
|
352
|
+
return Array.isArray(items) ? items.length : 0;
|
|
353
|
+
},
|
|
354
|
+
countInstances: name => countInstances(document, name),
|
|
355
|
+
hasDescendantWithTag: tag => hasDescendantWithTag(document, components, element.id, tag),
|
|
356
|
+
getAncestorInputs: name => {
|
|
357
|
+
const found = ancestors.find(a => a.manifest.name === name);
|
|
358
|
+
if (!found) {
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
361
|
+
const bindings = document.bindings[found.element.id]?.inputs ?? {};
|
|
362
|
+
return Object.fromEntries(Object.entries(bindings).map(([k, v]) => [k, v?.static]));
|
|
363
|
+
},
|
|
364
|
+
getElementInputs: () => {
|
|
365
|
+
const bindings = document.bindings[element.id]?.inputs ?? {};
|
|
366
|
+
return Object.fromEntries(Object.entries(bindings).map(([k, v]) => [k, v?.static]));
|
|
367
|
+
},
|
|
368
|
+
log: (...args) => console.log(...args),
|
|
369
|
+
block
|
|
370
|
+
};
|
|
371
|
+
const fallbackMessage = `${manifest.label} cannot be deleted.`;
|
|
372
|
+
try {
|
|
373
|
+
canDelete(ctx);
|
|
374
|
+
} catch (err) {
|
|
375
|
+
if (err instanceof ConstraintBlockError) {
|
|
376
|
+
return {
|
|
377
|
+
allowed: false,
|
|
378
|
+
violation: {
|
|
379
|
+
message: err.message
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
return {
|
|
384
|
+
allowed: false,
|
|
385
|
+
violation: {
|
|
386
|
+
message: err instanceof Error && err.message ? err.message : fallbackMessage
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
return {
|
|
391
|
+
allowed: true
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
//# sourceMappingURL=ConstraintEvaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["ConstraintBlockError","Error","constructor","message","block","buildSlotPattern","slot","match","undefined","RegExp","replace","findChildPosition","element","document","parent","id","inputs","bindings","slotName","test","directBinding","Array","isArray","static","index","indexOf","count","length","pattern","siblingKeys","key","m","push","idx","parseInt","sort","a","b","position","findIndex","val","includes","buildElementContext","components","manifest","component","name","tags","getParent","parentEl","elements","childIndex","pos","childCount","isLastChild","isFirstChild","buildAncestors","parentElement","ancestors","current","countInstances","componentName","hasDescendantWithTag","elementId","tag","el","isDescendant","elManifest","evaluateConstraints","params","parentId","componentManifest","allowed","parentCtx","parentInputs","ctx","isChildOf","isDescendantOf","some","getAncestor","found","find","hasTag","slotChildCount","items","getAncestorInputs","getElementInputs","log","args","console","runConstraint","constraint","fallbackMessage","err","constraints","violation","label","ancestor","descendantConstraints","evaluateDeleteConstraint","canDelete","elementCtx","Object","fromEntries","entries","map","k","v"],"sources":["ConstraintEvaluator.ts"],"sourcesContent":["import type {\n ComponentManifest,\n ComponentConstraint,\n ConstraintContext,\n ConstraintElementContext,\n Document,\n DocumentElement\n} from \"~/types.js\";\n\nclass ConstraintBlockError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nfunction block(message: string): never {\n throw new ConstraintBlockError(message);\n}\n\nexport type ConstraintViolation = {\n message: string;\n};\n\nexport type ConstraintResult = {\n allowed: boolean;\n violation?: ConstraintViolation;\n};\n\nexport interface EvaluateConstraintsParams {\n /** The component being placed */\n componentName: string;\n /** Target parent element ID */\n parentId: string;\n /** Target slot */\n slot: string;\n /** The document */\n document: Document;\n /** All registered component manifests */\n components: Record<string, ComponentManifest>;\n}\n\n/**\n * Build a regex pattern from a slot path, replacing the numeric index with \\d+.\n * E.g., \"steps/2/step\" → /^steps\\/\\d+\\/step$/\n * Returns undefined if the slot has no index segment.\n */\nfunction buildSlotPattern(slot: string): RegExp | undefined {\n const match = slot.match(/\\/(\\d+)\\//);\n if (!match) {\n return undefined;\n }\n return new RegExp(\"^\" + slot.replace(/\\/\\d+\\//, \"/\\\\d+/\") + \"$\");\n}\n\n/**\n * Find the actual index and sibling count for an element in its parent's bindings.\n * Instead of trusting element.parent.slot (which may be stale after reordering),\n * we scan the parent's binding keys to find which slot holds this element's ID.\n * Returns { index, count } or undefined if not in a list slot.\n */\nfunction findChildPosition(\n element: DocumentElement,\n document: Document\n): { index: number; count: number } | undefined {\n if (!element.parent?.id || !element.parent.slot) {\n return undefined;\n }\n\n const inputs = document.bindings[element.parent.id]?.inputs;\n if (!inputs) {\n return undefined;\n }\n\n // Try direct list slot format: binding key = slot name, static = array of IDs.\n // Only when the slot path itself is NOT an indexed sub-key (e.g., \"steps\", not \"steps/0/step\").\n const slotName = element.parent.slot;\n if (!/\\/\\d+\\//.test(slotName)) {\n const directBinding = inputs[slotName];\n if (directBinding && Array.isArray(directBinding.static)) {\n const index = directBinding.static.indexOf(element.id);\n if (index !== -1) {\n return { index, count: directBinding.static.length };\n }\n }\n }\n\n // Fall back to indexed sub-key format: steps/0/step, steps/1/step, etc.\n const pattern = buildSlotPattern(slotName);\n if (!pattern) {\n return undefined;\n }\n\n const siblingKeys: { key: string; idx: number }[] = [];\n for (const key in inputs) {\n if (pattern.test(key)) {\n const m = key.match(/\\/(\\d+)\\//);\n if (m) {\n siblingKeys.push({ key, idx: parseInt(m[1], 10) });\n }\n }\n }\n siblingKeys.sort((a, b) => a.idx - b.idx);\n\n const position = siblingKeys.findIndex(({ key }) => {\n const val = inputs[key]?.static;\n if (Array.isArray(val)) {\n return val.includes(element.id);\n }\n return val === element.id;\n });\n\n if (position === -1) {\n return undefined;\n }\n\n return { index: position, count: siblingKeys.length };\n}\n\nexport function buildElementContext(\n element: DocumentElement,\n components: Record<string, ComponentManifest>,\n document: Document\n): ConstraintElementContext | undefined {\n const manifest = components[element.component.name];\n if (!manifest) {\n return undefined;\n }\n\n return {\n name: element.component.name,\n tags: manifest.tags ?? [],\n getParent() {\n if (!element.parent?.id) {\n return undefined;\n }\n const parentEl = document.elements[element.parent.id];\n if (!parentEl) {\n return undefined;\n }\n return buildElementContext(parentEl, components, document);\n },\n childIndex() {\n const pos = findChildPosition(element, document);\n return pos ? pos.index : -1;\n },\n childCount() {\n const pos = findChildPosition(element, document);\n return pos ? pos.count : -1;\n },\n isLastChild() {\n const pos = findChildPosition(element, document);\n return pos !== undefined && pos.index === pos.count - 1;\n },\n isFirstChild() {\n const pos = findChildPosition(element, document);\n return pos !== undefined && pos.index === 0;\n }\n };\n}\n\nexport interface InternalAncestor {\n element: DocumentElement;\n manifest: ComponentManifest;\n}\n\nexport function buildAncestors(\n parentElement: DocumentElement,\n components: Record<string, ComponentManifest>,\n document: Document\n): InternalAncestor[] {\n const ancestors: InternalAncestor[] = [];\n let current: DocumentElement | undefined = parentElement;\n\n while (current) {\n const manifest = components[current.component.name];\n if (manifest) {\n ancestors.push({ element: current, manifest });\n }\n\n if (current.parent?.id) {\n current = document.elements[current.parent.id];\n } else {\n break;\n }\n }\n\n return ancestors;\n}\n\nfunction countInstances(document: Document, componentName: string): number {\n let count = 0;\n for (const id in document.elements) {\n if (document.elements[id].component.name === componentName) {\n count++;\n }\n }\n return count;\n}\n\nfunction hasDescendantWithTag(\n document: Document,\n components: Record<string, ComponentManifest>,\n elementId: string,\n tag: string\n): boolean {\n for (const id in document.elements) {\n const el = document.elements[id];\n if (id === elementId) {\n continue;\n }\n // Walk up parent chain to see if elementId is an ancestor.\n let current = el.parent?.id ? document.elements[el.parent.id] : undefined;\n let isDescendant = false;\n while (current) {\n if (current.id === elementId) {\n isDescendant = true;\n break;\n }\n current = current.parent?.id ? document.elements[current.parent.id] : undefined;\n }\n if (!isDescendant) {\n continue;\n }\n const elManifest = components[el.component.name];\n if (elManifest?.tags?.includes(tag)) {\n return true;\n }\n }\n return false;\n}\n\nexport function evaluateConstraints(params: EvaluateConstraintsParams): ConstraintResult {\n const { componentName, parentId, slot, document, components } = params;\n\n const componentManifest = components[componentName];\n if (!componentManifest) {\n return { allowed: true };\n }\n\n const parentElement = document.elements[parentId];\n if (!parentElement) {\n return { allowed: true };\n }\n\n const parentCtx = buildElementContext(parentElement, components, document);\n if (!parentCtx) {\n return { allowed: true };\n }\n\n const ancestors = buildAncestors(parentElement, components, document);\n\n const parentInputs = document.bindings[parentElement.id]?.inputs ?? {};\n\n const ctx: ConstraintContext = {\n component: {\n name: componentManifest.name,\n tags: componentManifest.tags ?? [],\n // During placement, the element doesn't exist yet — position is unknown.\n getParent: () => parentCtx,\n childIndex: () => -1,\n childCount: () => -1,\n isLastChild: () => false,\n isFirstChild: () => false\n },\n parent: parentCtx,\n slot,\n isChildOf: (name: string) => parentElement.component.name === name,\n isDescendantOf: (name: string) => ancestors.some(a => a.manifest.name === name),\n getAncestor: (name: string) => {\n const found = ancestors.find(a => a.manifest.name === name);\n return found ? buildElementContext(found.element, components, document) : undefined;\n },\n hasTag: (tag: string) => componentManifest.tags?.includes(tag) ?? false,\n slotChildCount: () => {\n const items = parentInputs[slot]?.static;\n return Array.isArray(items) ? items.length : 0;\n },\n countInstances: (name: string) => countInstances(document, name),\n // Element doesn't exist yet during placement — no descendants or inputs to check.\n hasDescendantWithTag: () => false,\n getAncestorInputs: () => undefined,\n getElementInputs: () => ({}),\n log: (...args: any[]) => console.log(...args),\n block\n };\n\n const runConstraint = (\n constraint: ComponentConstraint,\n fallbackMessage: string\n ): ConstraintViolation | undefined => {\n try {\n constraint(ctx);\n } catch (err) {\n if (err instanceof ConstraintBlockError) {\n return { message: err.message };\n }\n return {\n message: err instanceof Error && err.message ? err.message : fallbackMessage\n };\n }\n return undefined;\n };\n\n // Evaluate the placed component's own constraints.\n if (componentManifest.constraints) {\n for (const constraint of componentManifest.constraints) {\n const violation = runConstraint(\n constraint,\n `Cannot place ${componentManifest.label} here.`\n );\n if (violation) {\n return { allowed: false, violation };\n }\n }\n }\n\n // Evaluate descendantConstraints from all ancestors (including direct parent).\n for (const ancestor of ancestors) {\n if (ancestor.manifest.descendantConstraints) {\n for (const constraint of ancestor.manifest.descendantConstraints) {\n const violation = runConstraint(\n constraint,\n `Cannot place ${componentName} inside ${ancestor.manifest.label}.`\n );\n if (violation) {\n return { allowed: false, violation };\n }\n }\n }\n }\n\n return { allowed: true };\n}\n\nexport interface EvaluateDeleteConstraintParams {\n /** The element being deleted */\n elementId: string;\n /** The document */\n document: Document;\n /** All registered component manifests */\n components: Record<string, ComponentManifest>;\n}\n\nexport function evaluateDeleteConstraint(params: EvaluateDeleteConstraintParams): ConstraintResult {\n const { elementId, document, components } = params;\n\n const element = document.elements[elementId];\n if (!element) {\n return { allowed: true };\n }\n\n const manifest = components[element.component.name];\n if (!manifest) {\n return { allowed: true };\n }\n\n const { canDelete } = manifest;\n\n // undefined or true → allowed\n if (canDelete === undefined || canDelete === true) {\n return { allowed: true };\n }\n\n // false → blocked\n if (canDelete === false) {\n return {\n allowed: false,\n violation: {\n message: `${manifest.label} cannot be deleted.`\n }\n };\n }\n\n // ComponentConstraint → evaluate dynamically\n const parentElement = element.parent?.id ? document.elements[element.parent.id] : undefined;\n const parentCtx = parentElement\n ? buildElementContext(parentElement, components, document)\n : undefined;\n\n const ancestors = parentElement ? buildAncestors(parentElement, components, document) : [];\n\n const parentInputs = parentElement ? (document.bindings[parentElement.id]?.inputs ?? {}) : {};\n\n const slot = element.parent?.slot ?? \"\";\n\n const elementCtx = buildElementContext(element, components, document)!;\n\n const ctx: ConstraintContext = {\n component: elementCtx,\n parent: parentCtx ?? {\n name: \"\",\n tags: [],\n getParent: () => undefined,\n childIndex: () => -1,\n childCount: () => -1,\n isLastChild: () => false,\n isFirstChild: () => false\n },\n slot,\n isChildOf: (name: string) => parentElement?.component.name === name,\n isDescendantOf: (name: string) => ancestors.some(a => a.manifest.name === name),\n getAncestor: (name: string) => {\n const found = ancestors.find(a => a.manifest.name === name);\n return found ? buildElementContext(found.element, components, document) : undefined;\n },\n hasTag: (tag: string) => manifest.tags?.includes(tag) ?? false,\n slotChildCount: () => {\n const items = parentInputs[slot]?.static;\n return Array.isArray(items) ? items.length : 0;\n },\n countInstances: (name: string) => countInstances(document, name),\n hasDescendantWithTag: (tag: string) =>\n hasDescendantWithTag(document, components, element.id, tag),\n getAncestorInputs: (name: string) => {\n const found = ancestors.find(a => a.manifest.name === name);\n if (!found) {\n return undefined;\n }\n const bindings = document.bindings[found.element.id]?.inputs ?? {};\n return Object.fromEntries(\n Object.entries(bindings).map(([k, v]) => [k, (v as any)?.static])\n );\n },\n getElementInputs: () => {\n const bindings = document.bindings[element.id]?.inputs ?? {};\n return Object.fromEntries(\n Object.entries(bindings).map(([k, v]) => [k, (v as any)?.static])\n );\n },\n log: (...args: any[]) => console.log(...args),\n block\n };\n\n const fallbackMessage = `${manifest.label} cannot be deleted.`;\n try {\n canDelete(ctx);\n } catch (err) {\n if (err instanceof ConstraintBlockError) {\n return { allowed: false, violation: { message: err.message } };\n }\n return {\n allowed: false,\n violation: {\n message: err instanceof Error && err.message ? err.message : fallbackMessage\n }\n };\n }\n\n return { allowed: true };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|