sync-variable-plugin.ts 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import {
  2. definePluginCreator,
  3. FlowNodeVariableData,
  4. getNodeForm,
  5. PluginCreator,
  6. FreeLayoutPluginContext,
  7. ASTFactory,
  8. } from '@flowgram.ai/free-layout-editor';
  9. import { createASTFromJSONSchema } from './utils';
  10. export interface SyncVariablePluginOptions {}
  11. /**
  12. * Creates a plugin to synchronize output data to the variable engine when nodes are created or updated.
  13. * @param ctx - The plugin context, containing the document and other relevant information.
  14. * @param options - Plugin options, currently an empty object.
  15. */
  16. export const createSyncVariablePlugin: PluginCreator<SyncVariablePluginOptions> =
  17. definePluginCreator<SyncVariablePluginOptions, FreeLayoutPluginContext>({
  18. onInit(ctx, options) {
  19. const flowDocument = ctx.document;
  20. // Listen for node creation events
  21. flowDocument.onNodeCreate(({ node }) => {
  22. const form = getNodeForm(node);
  23. const variableData = node.getData(FlowNodeVariableData);
  24. /**
  25. * Synchronizes output data to the variable engine.
  26. * @param value - The output data to synchronize.
  27. */
  28. const syncOutputs = (value: any) => {
  29. if (!value) {
  30. // If the output data is empty, clear the variable
  31. variableData.clearVar();
  32. return;
  33. }
  34. // Create an Type AST from the output data's JSON schema
  35. // NOTICE: You can create a new function to generate an AST based on YOUR CUSTOM DSL
  36. const typeAST = createASTFromJSONSchema(value);
  37. if (typeAST) {
  38. // Use the node's title or its ID as the title for the variable
  39. const title = form?.getValueIn('title') || node.id;
  40. // Set the variable in the variable engine
  41. variableData.setVar(
  42. ASTFactory.createVariableDeclaration({
  43. meta: {
  44. title: `${title}`,
  45. icon: node.getNodeRegistry()?.info?.icon,
  46. // NOTICE: You can add more metadata here as needed
  47. },
  48. key: `${node.id}.outputs`,
  49. type: typeAST,
  50. })
  51. );
  52. } else {
  53. // If the AST cannot be created, clear the variable
  54. variableData.clearVar();
  55. }
  56. };
  57. if (form) {
  58. // Initially synchronize the output data
  59. syncOutputs(form.getValueIn('outputs'));
  60. // Listen for changes in the form values and re-synchronize when outputs change
  61. form.onFormValuesChange((props) => {
  62. if (props.name.match(/^outputs/) || props.name.match(/^title/)) {
  63. syncOutputs(form.getValueIn('outputs'));
  64. }
  65. });
  66. }
  67. });
  68. },
  69. });