Skip to content

Commit

Permalink
Macrofy 'Get Attribute' + generic util for simple string macros (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
GabiGrin authored Feb 19, 2024
1 parent ba30967 commit 78177e0
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 33 deletions.
10 changes: 5 additions & 5 deletions stdlib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@
"scripts": {
"test": "mocha src/**/*.spec.ts --require ts-node/register",
"echo": "echo 'no watch'",
"watch": "concurrently --kill-others \"pnpm run watch:ts\" \"pnpm run watch:docs-data\" \"pnpm run bundle:watch\"",
"watch": "concurrently --kill-others \"pnpm run watch:ts\" \"pnpm run watch:docs-data\" \"pnpm run macros:watch\"",
"watch:ts": "tsc -p . -w --incremental",
"watch:docs-data": "nodemon --watch scripts --watch src -e ts --exec \"ts-node scripts/docs-data.ts\"",
"dev": "pnpm run watch",
"bundle": "webpack --config webpack.config.js",
"bundle:watch": "webpack --config webpack.config.js --watch",
"build": "rm -rf dist && tsc -p tsconfig.build.json && pnpm run bundle && pnpm run build:docs-data",
"macros:bundle": "webpack --config webpack.config.js",
"macros:watch": "webpack --config webpack.config.js --watch",
"build": "rm -rf dist && tsc -p tsconfig.build.json && pnpm run macros:bundle && pnpm run build:docs-data",
"build:docs-data": "ts-node scripts/docs-data.ts",
"prod": "node dist/index.js",
"__publish": "npm version patch && npm publish"
}
}
}
49 changes: 49 additions & 0 deletions stdlib/src/Objects/GetAttribute/GetAttribute.flyde.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { InputPinMap, MacroNode } from "@flyde/core";
import { ConfigurableInput } from "../../lib/ConfigurableInput";

export interface GetAttributeConfig {
key: ConfigurableInput<{ value: string }>;
}

export const GetAttribute: MacroNode<GetAttributeConfig> = {
id: "GetAttribute",
searchKeywords: ["pick", "dot"],
namespace: "Lists",
defaultStyle: {
icon: "fa-magnifying-glass",
},
description: "Gets an attribute from an object",
definitionBuilder: (config) => {
const inputs: InputPinMap = {
object: {
description: "Object to get attribute from",
},
};
if (config.key.mode === "dynamic") {
inputs.attribute = {
description: "Attribute to get",
};
}
return {
inputs,
outputs: {
value: {
description: "The value of the attribute",
},
},
displayName: `Get Attribute${
config.key.mode === "static" ? ` "${config.key.value}"` : ""
}`,
};
},

runFnBuilder:
(config) =>
({ object, attribute }, { value }) => {
const _attribute =
config.key.mode === "static" ? config.key.value : attribute;
value.next(_attribute.split(".").reduce((obj, i) => obj[i], object));
},
defaultData: { key: { mode: "static", value: "" } },
editorComponentBundlePath: "../../../../dist/ui/GetAttribute.js",
};
7 changes: 7 additions & 0 deletions stdlib/src/Objects/GetAttribute/GetAttribute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { MacroEditorComp } from "../../lib/MacroEditorComp";
import { GetAttributeConfig } from "./GetAttribute.flyde";
import { SimpleStringMacroEditor } from "../../lib/SimpleStringMacroEditor";

const GetAttributeEditor: MacroEditorComp<GetAttributeConfig> =
SimpleStringMacroEditor<"key">("key", "Key:");
export default GetAttributeEditor;
53 changes: 28 additions & 25 deletions stdlib/src/Objects.flyde.ts → stdlib/src/Objects/Objects.flyde.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,35 @@
import { CodeNode } from "@flyde/core";

export * from "./GetAttribute/GetAttribute.flyde";

const namespace = "Objects";

/** @deprecated */
export const GetAttributeOld: CodeNode = {
id: "Get Attribute",
searchKeywords: ["pick", "dot"],
namespace,
defaultStyle: {
icon: "fa-magnifying-glass",
},
description: "Gets an attribute from an object",
inputs: {
object: {
description: "Object to get attribute from",
},
attribute: {
description: "Attribute to get",
},
},
outputs: {
value: {
description: "The value of the attribute",
},
},
run: ({ object, attribute }, { value }) =>
value.next(attribute.split(".").reduce((obj, i) => obj[i], object)),
};

export const JSONParse: CodeNode = {
id: "JSON Parse",
defaultStyle: {
Expand Down Expand Up @@ -59,31 +87,6 @@ export const ObjectEntries: CodeNode = {
run: ({ object }, { entries }) => entries.next(Object.entries(object)),
};

export const GetAttribute: CodeNode = {
id: "Get Attribute",
searchKeywords: ["pick", "dot"],
namespace,
defaultStyle: {
icon: "fa-magnifying-glass",
},
description: "Gets an attribute from an object",
inputs: {
object: {
description: "Object to get attribute from",
},
attribute: {
description: "Attribute to get",
},
},
outputs: {
value: {
description: "The value of the attribute",
},
},
run: ({ object, attribute }, { value }) =>
value.next(attribute.split(".").reduce((obj, i) => obj[i], object)),
};

export const SetAttribute: CodeNode = {
id: "Set Attribute",
searchKeywords: ["dot"],
Expand Down
2 changes: 1 addition & 1 deletion stdlib/src/all-browser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// consumed by the website playground
export * from "./Http/Http.flyde";
export * from "./Objects.flyde";
export * from "./Objects/Objects.flyde";
export * from "./Numbers.flyde";
export * from "./Strings.flyde";
export * from "./ControlFlow/ControlFlow.flyde";
Expand Down
4 changes: 3 additions & 1 deletion stdlib/src/lib/ConfigurableInputEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export const ConfigurableInputEditor = <T extends Record<string, any>>({
mode: "static",
});
};

const MemoValueRenderer = React.useMemo(() => ValueRenderer, []);
return (
<>
<RadioGroup
Expand All @@ -47,7 +49,7 @@ export const ConfigurableInputEditor = <T extends Record<string, any>>({
<Radio label="Dynamic" value="dynamic" />
</RadioGroup>
{value.mode === "static" ? (
<ValueRenderer value={value} onChange={handleValueChange} />
<MemoValueRenderer value={value} onChange={handleValueChange} />
) : null}
</>
);
Expand Down
37 changes: 37 additions & 0 deletions stdlib/src/lib/SimpleStringMacroEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from "react";
import { FormGroup, InputGroup } from "@blueprintjs/core";
import { ConfigurableInput } from "./ConfigurableInput";
import { ConfigurableInputEditor } from "./ConfigurableInputEditor";
import { MacroEditorComp } from "./MacroEditorComp";

export function SimpleStringMacroEditor<K extends string>(
key: K,
label: string
): MacroEditorComp<{ [P in K]: ConfigurableInput<{ value: string }> }> {
const Editor: MacroEditorComp<{
[P in K]: ConfigurableInput<{ value: string }>;
}> = function Editor({ value, onChange }) {
return (
<ConfigurableInputEditor
value={value[key]}
onChange={(newValue) => onChange({ ...value, [key]: newValue })}
valueRenderer={(vrProps) => (
<FormGroup label={label} inline>
<InputGroup
value={vrProps.value.value}
onChange={(e) =>
vrProps.onChange({
...vrProps.value,
value: e.target.value,
})
}
/>
</FormGroup>
)}
modeLabel="Key:"
defaultStaticValue={{ value: "" }}
/>
);
};
return Editor;
}
4 changes: 4 additions & 0 deletions stdlib/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const pairs = [
{ entry: "./src/Timing/Throttle.tsx", name: "Throttle" },
{ entry: "./src/Timing/Interval/Interval.tsx", name: "Interval" },
{ entry: "./src/Lists/Collect/Collect.tsx", name: "Collect" },
{
entry: "./src/Objects/GetAttribute/GetAttribute.tsx",
name: "GetAttribute",
},
];

module.exports = pairs.map(({ entry, name }) => ({
Expand Down
2 changes: 1 addition & 1 deletion website/docs/Reference/StdLib/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ For simplicity, all parts of Flyde's standard library reside in the same package

| Id | Description | Inputs | Outputs |
| -------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------- |
| **Get Attribute** | Gets an attribute from an object | <div><strong>object</strong>: Object to get attribute from (required)</div><div><strong>attribute</strong>: Attribute to get (required)</div> | <div><strong>value</strong>: The value of the attribute</div> |
| **JSON Parse** | Parses a JSON string into an object | <div><strong>json</strong>: JSON string to parse (required)</div> | <div><strong>object</strong>: The parsed object</div> |
| **JSON Stringify** | Stringifies an object into a JSON string | <div><strong>object</strong>: Object to stringify (required)</div> | <div><strong>json</strong>: The stringified JSON</div> |
| **Keys** | Emits the keys of an object | <div><strong>object</strong>: Object to get keys of (required)</div> | <div><strong>keys</strong>: The keys of object</div> |
| **Values** | Emits the values of an object | <div><strong>object</strong>: Object to get values of (required)</div> | <div><strong>values</strong>: The values of object</div> |
| **Entries** | Emits the entries of an object | <div><strong>object</strong>: Object to get entries of (required)</div> | <div><strong>entries</strong>: The entries of object</div> |
| **Get Attribute** | Gets an attribute from an object | <div><strong>object</strong>: Object to get attribute from (required)</div><div><strong>attribute</strong>: Attribute to get (required)</div> | <div><strong>value</strong>: The value of the attribute</div> |
| **Set Attribute** | Sets an attribute on an object | <div><strong>object</strong>: Object to set attribute on (required)</div><div><strong>attribute</strong>: Attribute to set (required)</div><div><strong>value</strong>: Value to set attribute to (required)</div> | <div><strong>object</strong>: The object with the attribute set</div> |
| **Delete Attribute** | Deletes an attribute from an object | <div><strong>object</strong>: Object to delete attribute from (required)</div><div><strong>attribute</strong>: Attribute to delete (required)</div> | <div><strong>object</strong>: The object with the attribute deleted</div> |

Expand Down

0 comments on commit 78177e0

Please sign in to comment.