@webstudio-is/react-sdk 0.81.0 → 0.83.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/LICENSE +661 -21
- package/lib/cjs/components/component-meta.js +5 -0
- package/lib/cjs/components/components-utils.js +1 -0
- package/lib/cjs/css/index.js +0 -1
- package/lib/cjs/embed-template.js +30 -1
- package/lib/cjs/expression.js +47 -4
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/props.js +6 -1
- package/lib/cjs/tree/root.js +1 -0
- package/lib/cjs/tree/webstudio-component.js +24 -10
- package/lib/components/component-meta.js +5 -0
- package/lib/components/components-utils.js +1 -0
- package/lib/css/index.js +0 -1
- package/lib/embed-template.js +38 -1
- package/lib/expression.js +47 -4
- package/lib/index.js +2 -0
- package/lib/props.js +6 -1
- package/lib/tree/create-elements-tree.js +3 -1
- package/lib/tree/root.js +8 -2
- package/lib/tree/webstudio-component.js +25 -11
- package/lib/types/app/root.d.ts +1 -2
- package/lib/types/components/component-meta.d.ts +16 -8
- package/lib/types/context.d.ts +1 -1
- package/lib/types/css/index.d.ts +0 -1
- package/lib/types/css/normalize.d.ts +47 -47
- package/lib/types/embed-template.d.ts +14 -1
- package/lib/types/expression.d.ts +3 -2
- package/lib/types/index.d.ts +1 -1
- package/lib/types/props.d.ts +1 -0
- package/lib/types/tree/create-elements-tree.d.ts +5 -5
- package/lib/types/tree/root.d.ts +4 -4
- package/lib/types/tree/webstudio-component.d.ts +15 -7
- package/package.json +14 -15
- package/src/components/component-meta.ts +5 -0
- package/src/context.tsx +1 -0
- package/src/css/index.ts +0 -1
- package/src/embed-template.test.ts +77 -1
- package/src/embed-template.ts +34 -1
- package/src/expression.test.ts +74 -6
- package/src/expression.ts +55 -2
- package/src/index.ts +1 -0
- package/src/props.ts +6 -1
- package/src/tree/create-elements-tree.tsx +17 -5
- package/src/tree/root.ts +14 -3
- package/src/tree/webstudio-component.tsx +41 -14
- package/lib/cjs/css/get-browser-style.js +0 -83
- package/lib/css/get-browser-style.js +0 -65
- package/lib/types/css/get-browser-style.d.ts +0 -2
- package/src/css/get-browser-style.ts +0 -81
|
@@ -218,13 +218,16 @@ declare const EmbedTemplateProp: z.ZodUnion<[z.ZodObject<{
|
|
|
218
218
|
name: z.ZodString;
|
|
219
219
|
value: z.ZodArray<z.ZodObject<{
|
|
220
220
|
type: z.ZodLiteral<"execute">;
|
|
221
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
221
222
|
code: z.ZodString;
|
|
222
223
|
}, "strip", z.ZodTypeAny, {
|
|
223
224
|
code: string;
|
|
224
225
|
type: "execute";
|
|
226
|
+
args?: string[] | undefined;
|
|
225
227
|
}, {
|
|
226
228
|
code: string;
|
|
227
229
|
type: "execute";
|
|
230
|
+
args?: string[] | undefined;
|
|
228
231
|
}>, "many">;
|
|
229
232
|
}, "strip", z.ZodTypeAny, {
|
|
230
233
|
name: string;
|
|
@@ -232,6 +235,7 @@ declare const EmbedTemplateProp: z.ZodUnion<[z.ZodObject<{
|
|
|
232
235
|
value: {
|
|
233
236
|
code: string;
|
|
234
237
|
type: "execute";
|
|
238
|
+
args?: string[] | undefined;
|
|
235
239
|
}[];
|
|
236
240
|
}, {
|
|
237
241
|
name: string;
|
|
@@ -239,6 +243,7 @@ declare const EmbedTemplateProp: z.ZodUnion<[z.ZodObject<{
|
|
|
239
243
|
value: {
|
|
240
244
|
code: string;
|
|
241
245
|
type: "execute";
|
|
246
|
+
args?: string[] | undefined;
|
|
242
247
|
}[];
|
|
243
248
|
}>]>;
|
|
244
249
|
type EmbedTemplateProp = z.infer<typeof EmbedTemplateProp>;
|
|
@@ -2390,6 +2395,7 @@ export declare const generateDataFromEmbedTemplate: (treeTemplate: ({
|
|
|
2390
2395
|
value: {
|
|
2391
2396
|
code: string;
|
|
2392
2397
|
type: "execute";
|
|
2398
|
+
args: string[];
|
|
2393
2399
|
}[];
|
|
2394
2400
|
id: string;
|
|
2395
2401
|
instanceId: string;
|
|
@@ -2645,8 +2651,15 @@ export declare const generateDataFromEmbedTemplate: (treeTemplate: ({
|
|
|
2645
2651
|
styleSourceId: string;
|
|
2646
2652
|
breakpointId: string;
|
|
2647
2653
|
state?: string | undefined;
|
|
2648
|
-
property: "filter" | "float" | "fontFamily" | "width" | "height" | "clip" | "top" | "right" | `--${string}` | "accentColor" | "alignContent" | "alignItems" | "alignSelf" | "alignTracks" | "animationComposition" | "animationDelay" | "animationDirection" | "animationDuration" | "animationFillMode" | "animationIterationCount" | "animationName" | "animationPlayState" | "animationTimingFunction" | "animationTimeline" | "appearance" | "aspectRatio" | "backdropFilter" | "backfaceVisibility" | "backgroundAttachment" | "backgroundBlendMode" | "backgroundClip" | "backgroundColor" | "backgroundImage" | "backgroundOrigin" | "backgroundPosition" | "backgroundPositionX" | "backgroundPositionY" | "backgroundRepeat" | "backgroundSize" | "blockOverflow" | "blockSize" | "borderBlockColor" | "borderBlockStyle" | "borderBlockWidth" | "borderBlockEndColor" | "borderBlockEndStyle" | "borderBlockEndWidth" | "borderBlockStartColor" | "borderBlockStartStyle" | "borderBlockStartWidth" | "borderBottomColor" | "borderBottomLeftRadius" | "borderBottomRightRadius" | "borderBottomStyle" | "borderBottomWidth" | "borderCollapse" | "borderEndEndRadius" | "borderEndStartRadius" | "borderImageOutset" | "borderImageRepeat" | "borderImageSlice" | "borderImageSource" | "borderImageWidth" | "borderInlineColor" | "borderInlineStyle" | "borderInlineWidth" | "borderInlineEndColor" | "borderInlineEndStyle" | "borderInlineEndWidth" | "borderInlineStartColor" | "borderInlineStartStyle" | "borderInlineStartWidth" | "borderLeftColor" | "borderLeftStyle" | "borderLeftWidth" | "borderRightColor" | "borderRightStyle" | "borderRightWidth" | "borderSpacing" | "borderStartEndRadius" | "borderStartStartRadius" | "borderTopColor" | "borderTopLeftRadius" | "borderTopRightRadius" | "borderTopStyle" | "borderTopWidth" | "bottom" | "boxDecorationBreak" | "boxShadow" | "boxSizing" | "breakAfter" | "breakBefore" | "breakInside" | "captionSide" | "caretColor" | "caretShape" | "clear" | "clipPath" | "color" | "printColorAdjust" | "colorScheme" | "columnCount" | "columnFill" | "columnGap" | "columnRuleColor" | "columnRuleStyle" | "columnRuleWidth" | "columnSpan" | "columnWidth" | "contain" | "containIntrinsicBlockSize" | "containIntrinsicHeight" | "containIntrinsicInlineSize" | "containIntrinsicWidth" | "content" | "contentVisibility" | "counterIncrement" | "counterReset" | "counterSet" | "cursor" | "direction" | "display" | "emptyCells" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontFeatureSettings" | "fontKerning" | "fontLanguageOverride" | "fontOpticalSizing" | "fontVariationSettings" | "fontSize" | "fontSizeAdjust" | "fontStretch" | "fontStyle" | "fontSynthesis" | "fontVariant" | "fontVariantAlternates" | "fontVariantCaps" | "fontVariantEastAsian" | "fontVariantLigatures" | "fontVariantNumeric" | "fontVariantPosition" | "fontWeight" | "forcedColorAdjust" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridColumnEnd" | "gridColumnStart" | "gridRowEnd" | "gridRowStart" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "hangingPunctuation" | "hyphenateCharacter" | "hyphens" | "imageOrientation" | "imageRendering" | "imageResolution" | "initialLetter" | "initialLetterAlign" | "inlineSize" | "inputSecurity" | "insetBlockEnd" | "insetBlockStart" | "insetInlineEnd" | "insetInlineStart" | "isolation" | "justifyContent" | "justifyItems" | "justifySelf" | "justifyTracks" | "left" | "letterSpacing" | "lineBreak" | "lineClamp" | "lineHeight" | "lineHeightStep" | "listStyleImage" | "listStylePosition" | "listStyleType" | "marginBlockEnd" | "marginBlockStart" | "marginBottom" | "marginInlineEnd" | "marginInlineStart" | "marginLeft" | "marginRight" | "marginTop" | "marginTrim" | "maskBorderMode" | "maskBorderOutset" | "maskBorderRepeat" | "maskBorderSlice" | "maskBorderSource" | "maskBorderWidth" | "maskClip" | "maskComposite" | "maskImage" | "maskMode" | "maskOrigin" | "maskPosition" | "maskRepeat" | "maskSize" | "maskType" | "masonryAutoFlow" | "mathDepth" | "mathShift" | "mathStyle" | "maxBlockSize" | "maxHeight" | "maxInlineSize" | "maxLines" | "maxWidth" | "minBlockSize" | "minHeight" | "minInlineSize" | "minWidth" | "mixBlendMode" | "objectFit" | "objectPosition" | "offsetAnchor" | "offsetDistance" | "offsetPath" | "offsetPosition" | "offsetRotate" | "opacity" | "order" | "orphans" | "outlineColor" | "outlineOffset" | "outlineStyle" | "outlineWidth" | "overflow" | "overflowAnchor" | "overflowBlock" | "overflowClipMargin" | "overflowInline" | "overflowWrap" | "overflowX" | "overflowY" | "overscrollBehavior" | "overscrollBehaviorBlock" | "overscrollBehaviorInline" | "overscrollBehaviorX" | "overscrollBehaviorY" | "paddingBlockEnd" | "paddingBlockStart" | "paddingBottom" | "paddingInlineEnd" | "paddingInlineStart" | "paddingLeft" | "paddingRight" | "paddingTop" | "pageBreakAfter" | "pageBreakBefore" | "pageBreakInside" | "paintOrder" | "perspective" | "perspectiveOrigin" | "pointerEvents" | "position" | "quotes" | "resize" | "rotate" | "rowGap" | "rubyAlign" | "rubyMerge" | "rubyPosition" | "scale" | "scrollbarColor" | "scrollbarGutter" | "scrollbarWidth" | "scrollBehavior" | "scrollMarginBlockStart" | "scrollMarginBlockEnd" | "scrollMarginBottom" | "scrollMarginInlineStart" | "scrollMarginInlineEnd" | "scrollMarginLeft" | "scrollMarginRight" | "scrollMarginTop" | "scrollPaddingBlockStart" | "scrollPaddingBlockEnd" | "scrollPaddingBottom" | "scrollPaddingInlineStart" | "scrollPaddingInlineEnd" | "scrollPaddingLeft" | "scrollPaddingRight" | "scrollPaddingTop" | "scrollSnapAlign" | "scrollSnapStop" | "scrollSnapType" | "scrollTimelineAxis" | "scrollTimelineName" | "shapeImageThreshold" | "shapeMargin" | "shapeOutside" | "tabSize" | "tableLayout" | "textAlign" | "textAlignLast" | "textCombineUpright" | "textDecorationColor" | "textDecorationLine" | "textDecorationSkip" | "textDecorationSkipInk" | "textDecorationStyle" | "textDecorationThickness" | "textEmphasisColor" | "textEmphasisPosition" | "textEmphasisStyle" | "textIndent" | "textJustify" | "textOrientation" | "textOverflow" | "textRendering" | "textShadow" | "textSizeAdjust" | "textTransform" | "textUnderlineOffset" | "textUnderlinePosition" | "touchAction" | "transform" | "transformBox" | "transformOrigin" | "transformStyle" | "transitionDelay" | "transitionDuration" | "transitionProperty" | "transitionTimingFunction" | "translate" | "unicodeBidi" | "userSelect" | "verticalAlign" | "visibility" | "whiteSpace" | "widows" | "willChange" | "wordBreak" | "wordSpacing" | "wordWrap" | "writingMode" | "zIndex";
|
|
2654
|
+
property: "filter" | "float" | "fontFamily" | "width" | "height" | "clip" | "top" | "right" | `--${string}` | "WebkitFontSmoothing" | "MozOsxFontSmoothing" | "accentColor" | "alignContent" | "alignItems" | "alignSelf" | "alignTracks" | "animationComposition" | "animationDelay" | "animationDirection" | "animationDuration" | "animationFillMode" | "animationIterationCount" | "animationName" | "animationPlayState" | "animationTimingFunction" | "animationTimeline" | "appearance" | "aspectRatio" | "backdropFilter" | "backfaceVisibility" | "backgroundAttachment" | "backgroundBlendMode" | "backgroundClip" | "backgroundColor" | "backgroundImage" | "backgroundOrigin" | "backgroundPosition" | "backgroundPositionX" | "backgroundPositionY" | "backgroundRepeat" | "backgroundSize" | "blockOverflow" | "blockSize" | "borderBlockColor" | "borderBlockStyle" | "borderBlockWidth" | "borderBlockEndColor" | "borderBlockEndStyle" | "borderBlockEndWidth" | "borderBlockStartColor" | "borderBlockStartStyle" | "borderBlockStartWidth" | "borderBottomColor" | "borderBottomLeftRadius" | "borderBottomRightRadius" | "borderBottomStyle" | "borderBottomWidth" | "borderCollapse" | "borderEndEndRadius" | "borderEndStartRadius" | "borderImageOutset" | "borderImageRepeat" | "borderImageSlice" | "borderImageSource" | "borderImageWidth" | "borderInlineColor" | "borderInlineStyle" | "borderInlineWidth" | "borderInlineEndColor" | "borderInlineEndStyle" | "borderInlineEndWidth" | "borderInlineStartColor" | "borderInlineStartStyle" | "borderInlineStartWidth" | "borderLeftColor" | "borderLeftStyle" | "borderLeftWidth" | "borderRightColor" | "borderRightStyle" | "borderRightWidth" | "borderSpacing" | "borderStartEndRadius" | "borderStartStartRadius" | "borderTopColor" | "borderTopLeftRadius" | "borderTopRightRadius" | "borderTopStyle" | "borderTopWidth" | "bottom" | "boxDecorationBreak" | "boxShadow" | "boxSizing" | "breakAfter" | "breakBefore" | "breakInside" | "captionSide" | "caretColor" | "caretShape" | "clear" | "clipPath" | "color" | "printColorAdjust" | "colorScheme" | "columnCount" | "columnFill" | "columnGap" | "columnRuleColor" | "columnRuleStyle" | "columnRuleWidth" | "columnSpan" | "columnWidth" | "contain" | "containIntrinsicBlockSize" | "containIntrinsicHeight" | "containIntrinsicInlineSize" | "containIntrinsicWidth" | "content" | "contentVisibility" | "counterIncrement" | "counterReset" | "counterSet" | "cursor" | "direction" | "display" | "emptyCells" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontFeatureSettings" | "fontKerning" | "fontLanguageOverride" | "fontOpticalSizing" | "fontVariationSettings" | "fontSize" | "fontSizeAdjust" | "fontStretch" | "fontStyle" | "fontSynthesis" | "fontVariant" | "fontVariantAlternates" | "fontVariantCaps" | "fontVariantEastAsian" | "fontVariantLigatures" | "fontVariantNumeric" | "fontVariantPosition" | "fontWeight" | "forcedColorAdjust" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridColumnEnd" | "gridColumnStart" | "gridRowEnd" | "gridRowStart" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "hangingPunctuation" | "hyphenateCharacter" | "hyphens" | "imageOrientation" | "imageRendering" | "imageResolution" | "initialLetter" | "initialLetterAlign" | "inlineSize" | "inputSecurity" | "insetBlockEnd" | "insetBlockStart" | "insetInlineEnd" | "insetInlineStart" | "isolation" | "justifyContent" | "justifyItems" | "justifySelf" | "justifyTracks" | "left" | "letterSpacing" | "lineBreak" | "lineClamp" | "lineHeight" | "lineHeightStep" | "listStyleImage" | "listStylePosition" | "listStyleType" | "marginBlockEnd" | "marginBlockStart" | "marginBottom" | "marginInlineEnd" | "marginInlineStart" | "marginLeft" | "marginRight" | "marginTop" | "marginTrim" | "maskBorderMode" | "maskBorderOutset" | "maskBorderRepeat" | "maskBorderSlice" | "maskBorderSource" | "maskBorderWidth" | "maskClip" | "maskComposite" | "maskImage" | "maskMode" | "maskOrigin" | "maskPosition" | "maskRepeat" | "maskSize" | "maskType" | "masonryAutoFlow" | "mathDepth" | "mathShift" | "mathStyle" | "maxBlockSize" | "maxHeight" | "maxInlineSize" | "maxLines" | "maxWidth" | "minBlockSize" | "minHeight" | "minInlineSize" | "minWidth" | "mixBlendMode" | "objectFit" | "objectPosition" | "offsetAnchor" | "offsetDistance" | "offsetPath" | "offsetPosition" | "offsetRotate" | "opacity" | "order" | "orphans" | "outlineColor" | "outlineOffset" | "outlineStyle" | "outlineWidth" | "overflow" | "overflowAnchor" | "overflowBlock" | "overflowClipMargin" | "overflowInline" | "overflowWrap" | "overflowX" | "overflowY" | "overscrollBehavior" | "overscrollBehaviorBlock" | "overscrollBehaviorInline" | "overscrollBehaviorX" | "overscrollBehaviorY" | "paddingBlockEnd" | "paddingBlockStart" | "paddingBottom" | "paddingInlineEnd" | "paddingInlineStart" | "paddingLeft" | "paddingRight" | "paddingTop" | "pageBreakAfter" | "pageBreakBefore" | "pageBreakInside" | "paintOrder" | "perspective" | "perspectiveOrigin" | "pointerEvents" | "position" | "quotes" | "resize" | "rotate" | "rowGap" | "rubyAlign" | "rubyMerge" | "rubyPosition" | "scale" | "scrollbarColor" | "scrollbarGutter" | "scrollbarWidth" | "scrollBehavior" | "scrollMarginBlockStart" | "scrollMarginBlockEnd" | "scrollMarginBottom" | "scrollMarginInlineStart" | "scrollMarginInlineEnd" | "scrollMarginLeft" | "scrollMarginRight" | "scrollMarginTop" | "scrollPaddingBlockStart" | "scrollPaddingBlockEnd" | "scrollPaddingBottom" | "scrollPaddingInlineStart" | "scrollPaddingInlineEnd" | "scrollPaddingLeft" | "scrollPaddingRight" | "scrollPaddingTop" | "scrollSnapAlign" | "scrollSnapStop" | "scrollSnapType" | "scrollTimelineAxis" | "scrollTimelineName" | "shapeImageThreshold" | "shapeMargin" | "shapeOutside" | "tabSize" | "tableLayout" | "textAlign" | "textAlignLast" | "textCombineUpright" | "textDecorationColor" | "textDecorationLine" | "textDecorationSkip" | "textDecorationSkipInk" | "textDecorationStyle" | "textDecorationThickness" | "textEmphasisColor" | "textEmphasisPosition" | "textEmphasisStyle" | "textIndent" | "textJustify" | "textOrientation" | "textOverflow" | "textRendering" | "textShadow" | "textSizeAdjust" | "textTransform" | "textUnderlineOffset" | "textUnderlinePosition" | "touchAction" | "transform" | "transformBox" | "transformOrigin" | "transformStyle" | "transitionDelay" | "transitionDuration" | "transitionProperty" | "transitionTimingFunction" | "translate" | "unicodeBidi" | "userSelect" | "verticalAlign" | "visibility" | "whiteSpace" | "widows" | "willChange" | "wordBreak" | "wordSpacing" | "wordWrap" | "writingMode" | "zIndex";
|
|
2649
2655
|
}[];
|
|
2650
2656
|
};
|
|
2651
2657
|
export type EmbedTemplateData = ReturnType<typeof generateDataFromEmbedTemplate>;
|
|
2658
|
+
export declare const namespaceEmbedTemplateComponents: (template: ({
|
|
2659
|
+
type: "text";
|
|
2660
|
+
value: string;
|
|
2661
|
+
} | EmbedTemplateInstance)[], namespace: string, components: Set<EmbedTemplateInstance["component"]>) => ({
|
|
2662
|
+
type: "text";
|
|
2663
|
+
value: string;
|
|
2664
|
+
} | EmbedTemplateInstance)[];
|
|
2652
2665
|
export {};
|
|
@@ -9,8 +9,9 @@ export declare const validateExpression: (code: string, options?: {
|
|
|
9
9
|
*/
|
|
10
10
|
export declare const generateComputingExpressions: (expressions: Map<string, string>, allowedVariables: Set<string>) => string;
|
|
11
11
|
export declare const executeComputingExpressions: (expressions: Map<string, string>, variables: Map<string, unknown>) => Map<string, unknown>;
|
|
12
|
-
export declare const generateEffectfulExpression: (code: string, allowedVariables: Set<string>) => string;
|
|
13
|
-
export declare const executeEffectfulExpression: (code: string, variables: Map<string, unknown>) => Map<string, unknown>;
|
|
12
|
+
export declare const generateEffectfulExpression: (code: string, args: Set<string>, allowedVariables: Set<string>) => string;
|
|
13
|
+
export declare const executeEffectfulExpression: (code: string, args: Map<string, unknown>, variables: Map<string, unknown>) => Map<string, unknown>;
|
|
14
|
+
export declare const computeExpressionsDependencies: (expressions: Map<string, string>) => Map<string, Set<string>>;
|
|
14
15
|
type Values = Map<string, unknown>;
|
|
15
16
|
export declare const encodeDataSourceVariable: (id: string) => string;
|
|
16
17
|
export declare const encodeVariablesMap: (values: Values) => Values;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ export { type WsComponentPropsMeta, type WsComponentMeta, type ComponentState, t
|
|
|
7
7
|
export * from "./embed-template";
|
|
8
8
|
export { useInstanceProps, usePropUrl, usePropAsset, getInstanceIdFromComponentProps, } from "./props";
|
|
9
9
|
export { type Params, ReactSdkContext } from "./context";
|
|
10
|
-
export { validateExpression, generateComputingExpressions, executeComputingExpressions, generateEffectfulExpression, executeEffectfulExpression, encodeDataSourceVariable, encodeVariablesMap, decodeDataSourceVariable, decodeVariablesMap, } from "./expression";
|
|
10
|
+
export { validateExpression, generateComputingExpressions, executeComputingExpressions, generateEffectfulExpression, executeEffectfulExpression, computeExpressionsDependencies, encodeDataSourceVariable, encodeVariablesMap, decodeDataSourceVariable, decodeVariablesMap, } from "./expression";
|
package/lib/types/props.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ForwardRefExoticComponent, type RefAttributes } from "react";
|
|
2
2
|
import type { ReadableAtom } from "nanostores";
|
|
3
3
|
import type { Assets } from "@webstudio-is/asset-uploader";
|
|
4
4
|
import type { Instance, Instances } from "@webstudio-is/project-build";
|
|
5
5
|
import type { Components } from "../components/components-utils";
|
|
6
6
|
import { type Params, type DataSourceValues } from "../context";
|
|
7
7
|
import type { Pages, PropsByInstanceId } from "../props";
|
|
8
|
-
import type {
|
|
8
|
+
import type { WebstudioComponentProps } from "./webstudio-component";
|
|
9
9
|
export declare const createElementsTree: ({ renderer, imageBaseUrl, assetBaseUrl, instances, rootInstanceId, propsByInstanceIdStore, assetsStore, pagesStore, dataSourceValuesStore, executeEffectfulExpression, onDataSourceUpdate, Component, components, }: Params & {
|
|
10
10
|
instances: Map<string, {
|
|
11
11
|
type: "instance";
|
|
@@ -24,9 +24,9 @@ export declare const createElementsTree: ({ renderer, imageBaseUrl, assetBaseUrl
|
|
|
24
24
|
propsByInstanceIdStore: ReadableAtom<PropsByInstanceId>;
|
|
25
25
|
assetsStore: ReadableAtom<Assets>;
|
|
26
26
|
pagesStore: ReadableAtom<Pages>;
|
|
27
|
-
executeEffectfulExpression: (expression: string, values: DataSourceValues) => DataSourceValues;
|
|
27
|
+
executeEffectfulExpression: (expression: string, args: DataSourceValues, values: DataSourceValues) => DataSourceValues;
|
|
28
28
|
dataSourceValuesStore: ReadableAtom<DataSourceValues>;
|
|
29
29
|
onDataSourceUpdate: (newValues: DataSourceValues) => void;
|
|
30
|
-
Component:
|
|
30
|
+
Component: ForwardRefExoticComponent<WebstudioComponentProps & RefAttributes<HTMLElement>>;
|
|
31
31
|
components: Components;
|
|
32
|
-
}) => JSX.Element | null;
|
|
32
|
+
}) => import("react/jsx-runtime").JSX.Element | null;
|
package/lib/types/tree/root.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ForwardRefExoticComponent, type RefAttributes } from "react";
|
|
2
2
|
import { type Build, type Page } from "@webstudio-is/project-build";
|
|
3
3
|
import type { Asset } from "@webstudio-is/asset-uploader";
|
|
4
|
-
import {
|
|
4
|
+
import { type WebstudioComponentProps } from "./webstudio-component";
|
|
5
5
|
import type { Components } from "../components/components-utils";
|
|
6
6
|
import type { Params, DataSourceValues } from "../context";
|
|
7
7
|
export type Data = {
|
|
@@ -17,8 +17,8 @@ export type RootPropsData = Omit<Data, "build"> & {
|
|
|
17
17
|
type RootProps = {
|
|
18
18
|
data: RootPropsData;
|
|
19
19
|
executeComputingExpressions: (values: DataSourceValues) => DataSourceValues;
|
|
20
|
-
executeEffectfulExpression: (expression: string, values: DataSourceValues) => DataSourceValues;
|
|
21
|
-
Component?:
|
|
20
|
+
executeEffectfulExpression: (expression: string, args: DataSourceValues, values: DataSourceValues) => DataSourceValues;
|
|
21
|
+
Component?: ForwardRefExoticComponent<WebstudioComponentProps & RefAttributes<HTMLElement>>;
|
|
22
22
|
components: Components;
|
|
23
23
|
};
|
|
24
24
|
export declare const InstanceRoot: ({ data, executeComputingExpressions, executeEffectfulExpression, Component, components, }: RootProps) => JSX.Element | null;
|
|
@@ -2,15 +2,23 @@
|
|
|
2
2
|
import type { Instance } from "@webstudio-is/project-build";
|
|
3
3
|
import type { Components } from "../components/components-utils";
|
|
4
4
|
export declare const renderWebstudioComponentChildren: (children: Array<JSX.Element | string> | undefined) => Array<JSX.Element | string | Array<JSX.Element | string>> | undefined;
|
|
5
|
-
type WebstudioComponentProps = {
|
|
5
|
+
export type WebstudioComponentProps = {
|
|
6
6
|
instance: Instance;
|
|
7
7
|
instanceSelector: Instance["id"][];
|
|
8
8
|
children: Array<JSX.Element | string>;
|
|
9
9
|
components: Components;
|
|
10
10
|
};
|
|
11
|
-
export declare const WebstudioComponent: (
|
|
12
|
-
export declare const idAttribute
|
|
13
|
-
export declare const
|
|
14
|
-
export declare const
|
|
15
|
-
export declare const
|
|
16
|
-
export
|
|
11
|
+
export declare const WebstudioComponent: import("react").ForwardRefExoticComponent<WebstudioComponentProps & import("react").RefAttributes<HTMLElement>>;
|
|
12
|
+
export declare const idAttribute: "data-ws-id";
|
|
13
|
+
export declare const selectorIdAttribute: "data-ws-selector";
|
|
14
|
+
export declare const componentAttribute: "data-ws-component";
|
|
15
|
+
export declare const showAttribute: "data-ws-show";
|
|
16
|
+
export declare const collapsedAttribute: "data-ws-collapsed";
|
|
17
|
+
export type WebstudioAttributes = {
|
|
18
|
+
[idAttribute]?: string | undefined;
|
|
19
|
+
[selectorIdAttribute]?: string | undefined;
|
|
20
|
+
[componentAttribute]?: string | undefined;
|
|
21
|
+
[showAttribute]?: string | undefined;
|
|
22
|
+
[collapsedAttribute]?: string | undefined;
|
|
23
|
+
};
|
|
24
|
+
export declare const splitPropsWithWebstudioAttributes: <P extends WebstudioAttributes>({ [idAttribute]: idAttributeValue, [componentAttribute]: componentAttributeValue, [showAttribute]: showAttributeValue, [collapsedAttribute]: collapsedAttributeValue, [selectorIdAttribute]: parentIdAttributeValue, ...props }: P) => [WebstudioAttributes, Omit<P, keyof WebstudioAttributes>];
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webstudio-is/react-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.83.0",
|
|
4
4
|
"description": "Webstudio JavaScript / TypeScript API",
|
|
5
5
|
"author": "Webstudio <github@webstudio.is>",
|
|
6
6
|
"homepage": "https://webstudio.is",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"devDependencies": {
|
|
9
|
-
"@jest/globals": "^29.6.
|
|
9
|
+
"@jest/globals": "^29.6.2",
|
|
10
10
|
"@remix-run/react": "^1.18.1",
|
|
11
|
-
"@types/react": "^18.
|
|
12
|
-
"@types/react-dom": "^18.
|
|
13
|
-
"jest": "^29.6.
|
|
11
|
+
"@types/react": "^18.2.16",
|
|
12
|
+
"@types/react-dom": "^18.2.7",
|
|
13
|
+
"jest": "^29.6.2",
|
|
14
14
|
"react": "^18.2.0",
|
|
15
15
|
"react-dom": "^18.2.0",
|
|
16
16
|
"type-fest": "^3.7.1",
|
|
17
|
-
"typescript": "5.1.
|
|
17
|
+
"typescript": "5.1.6",
|
|
18
18
|
"zod": "^3.21.4",
|
|
19
19
|
"@webstudio-is/jest-config": "^1.0.6",
|
|
20
20
|
"@webstudio-is/scripts": "^0.0.0",
|
|
@@ -29,18 +29,17 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@jsep-plugin/assignment": "^1.2.1",
|
|
31
31
|
"@nanostores/react": "^0.7.1",
|
|
32
|
-
"detect-font": "^0.1.5",
|
|
33
32
|
"html-tags": "^3.3.1",
|
|
34
33
|
"jsep": "^1.3.8",
|
|
35
34
|
"nanoevents": "^8.0.0",
|
|
36
35
|
"nanoid": "^4.0.2",
|
|
37
36
|
"nanostores": "^0.9.3",
|
|
38
|
-
"@webstudio-is/asset-uploader": "^0.
|
|
39
|
-
"@webstudio-is/css-data": "^0.
|
|
40
|
-
"@webstudio-is/css-engine": "^0.
|
|
41
|
-
"@webstudio-is/fonts": "^0.
|
|
42
|
-
"@webstudio-is/generate-arg-types": "^0.
|
|
43
|
-
"@webstudio-is/project-build": "^0.
|
|
37
|
+
"@webstudio-is/asset-uploader": "^0.83.0",
|
|
38
|
+
"@webstudio-is/css-data": "^0.83.0",
|
|
39
|
+
"@webstudio-is/css-engine": "^0.83.0",
|
|
40
|
+
"@webstudio-is/fonts": "^0.83.0",
|
|
41
|
+
"@webstudio-is/generate-arg-types": "^0.83.0",
|
|
42
|
+
"@webstudio-is/project-build": "^0.83.0"
|
|
44
43
|
},
|
|
45
44
|
"exports": {
|
|
46
45
|
".": {
|
|
@@ -61,7 +60,7 @@
|
|
|
61
60
|
"src/*",
|
|
62
61
|
"!*.test.*"
|
|
63
62
|
],
|
|
64
|
-
"license": "
|
|
63
|
+
"license": "AGPL-3.0-or-later",
|
|
65
64
|
"private": false,
|
|
66
65
|
"sideEffects": false,
|
|
67
66
|
"scripts": {
|
|
@@ -69,7 +68,7 @@
|
|
|
69
68
|
"build": "build-package",
|
|
70
69
|
"build:args": "generate-arg-types './src/components/*.tsx ./src/app/custom-components/*.tsx !./src/**/*.stories.tsx !./src/**/*.ws.tsx' && prettier --write \"**/*.props.ts\"",
|
|
71
70
|
"dts": "tsc --project tsconfig.dts.json",
|
|
72
|
-
"typecheck": "tsc
|
|
71
|
+
"typecheck": "tsc",
|
|
73
72
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest --passWithNoTests",
|
|
74
73
|
"checks": "pnpm typecheck && pnpm test"
|
|
75
74
|
}
|
|
@@ -22,6 +22,7 @@ export const componentCategories = [
|
|
|
22
22
|
"text",
|
|
23
23
|
"media",
|
|
24
24
|
"forms",
|
|
25
|
+
"radix",
|
|
25
26
|
"hidden",
|
|
26
27
|
] as const;
|
|
27
28
|
|
|
@@ -53,6 +54,10 @@ const WsComponentMeta = z.object({
|
|
|
53
54
|
requiredAncestors: z.optional(z.array(z.string())),
|
|
54
55
|
invalidAncestors: z.optional(z.array(z.string())),
|
|
55
56
|
stylable: z.optional(z.boolean()),
|
|
57
|
+
// specifies whether the instance can be deleted,
|
|
58
|
+
// copied or dragged out of its parent instance
|
|
59
|
+
// true by default
|
|
60
|
+
detachable: z.optional(z.boolean()),
|
|
56
61
|
label: z.string(),
|
|
57
62
|
description: z.string().optional(),
|
|
58
63
|
icon: z.string(),
|
package/src/context.tsx
CHANGED
|
@@ -41,6 +41,7 @@ export const ReactSdkContext = createContext<
|
|
|
41
41
|
dataSourceValuesStore: ReadableAtom<DataSourceValues>;
|
|
42
42
|
executeEffectfulExpression: (
|
|
43
43
|
expression: string,
|
|
44
|
+
args: DataSourceValues,
|
|
44
45
|
values: DataSourceValues
|
|
45
46
|
) => DataSourceValues;
|
|
46
47
|
setDataSourceValues: (newValues: DataSourceValues) => void;
|
package/src/css/index.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { expect, test } from "@jest/globals";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
generateDataFromEmbedTemplate,
|
|
4
|
+
namespaceEmbedTemplateComponents,
|
|
5
|
+
} from "./embed-template";
|
|
3
6
|
import { showAttribute } from "./tree";
|
|
4
7
|
|
|
5
8
|
const expectString = expect.any(String);
|
|
@@ -407,6 +410,17 @@ test("generate data for embedding from action props", () => {
|
|
|
407
410
|
name: "onClick",
|
|
408
411
|
value: [{ type: "execute", code: `boxState = 'success'` }],
|
|
409
412
|
},
|
|
413
|
+
{
|
|
414
|
+
type: "action",
|
|
415
|
+
name: "onChange",
|
|
416
|
+
value: [
|
|
417
|
+
{
|
|
418
|
+
type: "execute",
|
|
419
|
+
args: ["value"],
|
|
420
|
+
code: `boxState = value`,
|
|
421
|
+
},
|
|
422
|
+
],
|
|
423
|
+
},
|
|
410
424
|
],
|
|
411
425
|
children: [],
|
|
412
426
|
},
|
|
@@ -442,10 +456,24 @@ test("generate data for embedding from action props", () => {
|
|
|
442
456
|
value: [
|
|
443
457
|
{
|
|
444
458
|
type: "execute",
|
|
459
|
+
args: [],
|
|
445
460
|
code: expect.stringMatching(/\$ws\$dataSource\$\w+ = 'success'/),
|
|
446
461
|
},
|
|
447
462
|
],
|
|
448
463
|
},
|
|
464
|
+
{
|
|
465
|
+
id: expectString,
|
|
466
|
+
instanceId: expectString,
|
|
467
|
+
type: "action",
|
|
468
|
+
name: "onChange",
|
|
469
|
+
value: [
|
|
470
|
+
{
|
|
471
|
+
type: "execute",
|
|
472
|
+
args: ["value"],
|
|
473
|
+
code: expect.stringMatching(/\$ws\$dataSource\$\w+ = value/),
|
|
474
|
+
},
|
|
475
|
+
],
|
|
476
|
+
},
|
|
449
477
|
],
|
|
450
478
|
dataSources: [
|
|
451
479
|
{
|
|
@@ -464,3 +492,51 @@ test("generate data for embedding from action props", () => {
|
|
|
464
492
|
styles: [],
|
|
465
493
|
});
|
|
466
494
|
});
|
|
495
|
+
|
|
496
|
+
test("add namespace to selected components in embed template", () => {
|
|
497
|
+
expect(
|
|
498
|
+
namespaceEmbedTemplateComponents(
|
|
499
|
+
[
|
|
500
|
+
{
|
|
501
|
+
type: "instance",
|
|
502
|
+
component: "Tooltip",
|
|
503
|
+
children: [
|
|
504
|
+
{ type: "text", value: "Some text" },
|
|
505
|
+
{
|
|
506
|
+
type: "instance",
|
|
507
|
+
component: "Box",
|
|
508
|
+
children: [
|
|
509
|
+
{
|
|
510
|
+
type: "instance",
|
|
511
|
+
component: "Button",
|
|
512
|
+
children: [],
|
|
513
|
+
},
|
|
514
|
+
],
|
|
515
|
+
},
|
|
516
|
+
],
|
|
517
|
+
},
|
|
518
|
+
],
|
|
519
|
+
"my-namespace",
|
|
520
|
+
new Set(["Tooltip", "Button"])
|
|
521
|
+
)
|
|
522
|
+
).toEqual([
|
|
523
|
+
{
|
|
524
|
+
type: "instance",
|
|
525
|
+
component: "my-namespace:Tooltip",
|
|
526
|
+
children: [
|
|
527
|
+
{ type: "text", value: "Some text" },
|
|
528
|
+
{
|
|
529
|
+
type: "instance",
|
|
530
|
+
component: "Box",
|
|
531
|
+
children: [
|
|
532
|
+
{
|
|
533
|
+
type: "instance",
|
|
534
|
+
component: "my-namespace:Button",
|
|
535
|
+
children: [],
|
|
536
|
+
},
|
|
537
|
+
],
|
|
538
|
+
},
|
|
539
|
+
],
|
|
540
|
+
},
|
|
541
|
+
]);
|
|
542
|
+
});
|
package/src/embed-template.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { nanoid } from "nanoid";
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
Instance,
|
|
5
5
|
type InstancesList,
|
|
6
6
|
PropsList,
|
|
7
7
|
StyleSourceSelectionsList,
|
|
@@ -66,6 +66,7 @@ const EmbedTemplateProp = z.union([
|
|
|
66
66
|
value: z.array(
|
|
67
67
|
z.object({
|
|
68
68
|
type: z.literal("execute"),
|
|
69
|
+
args: z.optional(z.array(z.string())),
|
|
69
70
|
code: z.string(),
|
|
70
71
|
})
|
|
71
72
|
),
|
|
@@ -144,12 +145,18 @@ const createInstancesFromTemplate = (
|
|
|
144
145
|
type: "action",
|
|
145
146
|
name: prop.name,
|
|
146
147
|
value: prop.value.map((value) => {
|
|
148
|
+
const args = value.args ?? [];
|
|
147
149
|
return {
|
|
148
150
|
type: "execute",
|
|
151
|
+
args,
|
|
149
152
|
// replace all references with variable names
|
|
150
153
|
code: validateExpression(value.code, {
|
|
151
154
|
effectful: true,
|
|
152
155
|
transformIdentifier: (ref) => {
|
|
156
|
+
// bypass arguments without changes
|
|
157
|
+
if (args.includes(ref)) {
|
|
158
|
+
return ref;
|
|
159
|
+
}
|
|
153
160
|
const id = dataSourceByRef.get(ref)?.id ?? ref;
|
|
154
161
|
return encodeDataSourceVariable(id);
|
|
155
162
|
},
|
|
@@ -301,3 +308,29 @@ export const generateDataFromEmbedTemplate = (
|
|
|
301
308
|
export type EmbedTemplateData = ReturnType<
|
|
302
309
|
typeof generateDataFromEmbedTemplate
|
|
303
310
|
>;
|
|
311
|
+
|
|
312
|
+
export const namespaceEmbedTemplateComponents = (
|
|
313
|
+
template: WsEmbedTemplate,
|
|
314
|
+
namespace: string,
|
|
315
|
+
components: Set<EmbedTemplateInstance["component"]>
|
|
316
|
+
): WsEmbedTemplate => {
|
|
317
|
+
return template.map((item) => {
|
|
318
|
+
if (item.type === "text") {
|
|
319
|
+
return item;
|
|
320
|
+
}
|
|
321
|
+
if (item.type === "instance") {
|
|
322
|
+
const prefix = components.has(item.component) ? `${namespace}:` : "";
|
|
323
|
+
return {
|
|
324
|
+
...item,
|
|
325
|
+
component: `${prefix}${item.component}`,
|
|
326
|
+
children: namespaceEmbedTemplateComponents(
|
|
327
|
+
item.children,
|
|
328
|
+
namespace,
|
|
329
|
+
components
|
|
330
|
+
),
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
item satisfies never;
|
|
334
|
+
throw Error("Impossible case");
|
|
335
|
+
});
|
|
336
|
+
};
|
package/src/expression.test.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
encodeDataSourceVariable,
|
|
5
5
|
executeComputingExpressions,
|
|
6
6
|
executeEffectfulExpression,
|
|
7
|
+
computeExpressionsDependencies,
|
|
7
8
|
generateComputingExpressions,
|
|
8
9
|
generateEffectfulExpression,
|
|
9
10
|
validateExpression,
|
|
@@ -186,7 +187,11 @@ test("encode/decode variable names", () => {
|
|
|
186
187
|
|
|
187
188
|
test("generate effectful expression", () => {
|
|
188
189
|
expect(
|
|
189
|
-
generateEffectfulExpression(
|
|
190
|
+
generateEffectfulExpression(
|
|
191
|
+
`var0 = var0 + var1`,
|
|
192
|
+
new Set(),
|
|
193
|
+
new Set(["var0", "var1"])
|
|
194
|
+
)
|
|
190
195
|
).toMatchInlineSnapshot(`
|
|
191
196
|
"let var0 = _variables.get('var0');
|
|
192
197
|
let var1 = _variables.get('var1');
|
|
@@ -197,7 +202,11 @@ test("generate effectful expression", () => {
|
|
|
197
202
|
`);
|
|
198
203
|
|
|
199
204
|
expect(
|
|
200
|
-
generateEffectfulExpression(
|
|
205
|
+
generateEffectfulExpression(
|
|
206
|
+
`var0 = var1 + 1`,
|
|
207
|
+
new Set(),
|
|
208
|
+
new Set(["var0", "var1"])
|
|
209
|
+
)
|
|
201
210
|
).toMatchInlineSnapshot(`
|
|
202
211
|
"let var1 = _variables.get('var1');
|
|
203
212
|
let var0;
|
|
@@ -212,6 +221,7 @@ test("add only used variables in effectful expression", () => {
|
|
|
212
221
|
expect(
|
|
213
222
|
generateEffectfulExpression(
|
|
214
223
|
`var0 = var1 + 1`,
|
|
224
|
+
new Set(),
|
|
215
225
|
new Set(["var0", "var1", "var2"])
|
|
216
226
|
)
|
|
217
227
|
).toMatchInlineSnapshot(`
|
|
@@ -224,10 +234,34 @@ test("add only used variables in effectful expression", () => {
|
|
|
224
234
|
`);
|
|
225
235
|
});
|
|
226
236
|
|
|
227
|
-
test("
|
|
237
|
+
test("support effectful expression arguments", () => {
|
|
238
|
+
expect(
|
|
239
|
+
generateEffectfulExpression(
|
|
240
|
+
`var0 = arg0 + 1`,
|
|
241
|
+
new Set(["arg0"]),
|
|
242
|
+
new Set(["var0"])
|
|
243
|
+
)
|
|
244
|
+
).toMatchInlineSnapshot(`
|
|
245
|
+
"let arg0 = _args.get('arg0');
|
|
246
|
+
let var0;
|
|
247
|
+
var0 = arg0 + 1;
|
|
248
|
+
return new Map([
|
|
249
|
+
['var0', var0],
|
|
250
|
+
]);"
|
|
251
|
+
`);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test("forbid not allowed variables or arguments in effectful expression", () => {
|
|
228
255
|
expect(() => {
|
|
229
|
-
generateEffectfulExpression(
|
|
256
|
+
generateEffectfulExpression(
|
|
257
|
+
`var0 = var0 + var1`,
|
|
258
|
+
new Set(),
|
|
259
|
+
new Set(["var0"])
|
|
260
|
+
);
|
|
230
261
|
}).toThrowError(/Unknown dependency "var1"/);
|
|
262
|
+
expect(() => {
|
|
263
|
+
generateEffectfulExpression(`var0 = arg0`, new Set(), new Set(["var0"]));
|
|
264
|
+
}).toThrowError(/Unknown dependency "arg0"/);
|
|
231
265
|
});
|
|
232
266
|
|
|
233
267
|
test("execute effectful expression", () => {
|
|
@@ -235,7 +269,41 @@ test("execute effectful expression", () => {
|
|
|
235
269
|
["var0", 2],
|
|
236
270
|
["var1", 3],
|
|
237
271
|
]);
|
|
238
|
-
expect(
|
|
239
|
-
new Map(
|
|
272
|
+
expect(
|
|
273
|
+
executeEffectfulExpression(`var0 = var0 + var1`, new Map(), variables)
|
|
274
|
+
).toEqual(new Map([["var0", 5]]));
|
|
275
|
+
|
|
276
|
+
expect(
|
|
277
|
+
executeEffectfulExpression(`arg0 = 5`, new Map([["arg0", 0]]), new Map())
|
|
278
|
+
).toEqual(new Map());
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
test("compute expressions dependencies", () => {
|
|
282
|
+
const expressions = new Map([
|
|
283
|
+
["exp1", `var1`],
|
|
284
|
+
["exp2", `exp1 + exp1`],
|
|
285
|
+
["exp3", `exp1 + exp2`],
|
|
286
|
+
["exp4", `var1 + exp1`],
|
|
287
|
+
]);
|
|
288
|
+
expect(computeExpressionsDependencies(expressions)).toEqual(
|
|
289
|
+
new Map([
|
|
290
|
+
["exp4", new Set(["var1", "exp1"])],
|
|
291
|
+
["exp3", new Set(["var1", "exp1", "exp2"])],
|
|
292
|
+
["exp2", new Set(["var1", "exp1"])],
|
|
293
|
+
["exp1", new Set(["var1"])],
|
|
294
|
+
])
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test("handle cyclic dependencies", () => {
|
|
299
|
+
const expressions = new Map([
|
|
300
|
+
["exp1", `exp2 + var1`],
|
|
301
|
+
["exp2", `exp1 + var1`],
|
|
302
|
+
]);
|
|
303
|
+
expect(computeExpressionsDependencies(expressions)).toEqual(
|
|
304
|
+
new Map([
|
|
305
|
+
["exp2", new Set(["var1", "exp1", "exp2"])],
|
|
306
|
+
["exp1", new Set(["var1", "exp1", "exp2"])],
|
|
307
|
+
])
|
|
240
308
|
);
|
|
241
309
|
});
|