@flowgram-vue/form-core 0.2.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.
Files changed (83) hide show
  1. package/LICENSE +22 -0
  2. package/dist/index.cjs +0 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +0 -0
  6. package/dist/index.js.map +1 -0
  7. package/package.json +66 -0
  8. package/src/client/NodeRender.vue +76 -0
  9. package/src/client/create-node-container-modules.ts +12 -0
  10. package/src/client/create-node-entity-datas.ts +13 -0
  11. package/src/client/index.ts +11 -0
  12. package/src/client/node-material-client.ts +18 -0
  13. package/src/client/node-render.ts +6 -0
  14. package/src/env.d.ts +10 -0
  15. package/src/error/client.ts +12 -0
  16. package/src/error/error-container-module.ts +14 -0
  17. package/src/error/error-node-contribution.ts +17 -0
  18. package/src/error/flow-node-error-data.ts +26 -0
  19. package/src/error/index.ts +9 -0
  20. package/src/error/renders/ErrorRender.vue +61 -0
  21. package/src/error/renders/default-error-render.ts +15 -0
  22. package/src/error/renders/error-render.ts +19 -0
  23. package/src/error/renders/index.ts +6 -0
  24. package/src/error/types.ts +13 -0
  25. package/src/form/FormRender.vue +39 -0
  26. package/src/form/abilities/decorator-ability/decorator-ability.ts +14 -0
  27. package/src/form/abilities/decorator-ability/index.ts +7 -0
  28. package/src/form/abilities/decorator-ability/types.ts +28 -0
  29. package/src/form/abilities/default-ability/default-ability.ts +14 -0
  30. package/src/form/abilities/default-ability/index.ts +7 -0
  31. package/src/form/abilities/default-ability/types.ts +15 -0
  32. package/src/form/abilities/effect-ability/effect-ability.ts +14 -0
  33. package/src/form/abilities/effect-ability/index.ts +7 -0
  34. package/src/form/abilities/effect-ability/types.ts +41 -0
  35. package/src/form/abilities/index.ts +11 -0
  36. package/src/form/abilities/setter-ability/index.ts +7 -0
  37. package/src/form/abilities/setter-ability/setter-ability.ts +14 -0
  38. package/src/form/abilities/setter-ability/types.ts +52 -0
  39. package/src/form/abilities/validation-ability/form-validate.types.ts +74 -0
  40. package/src/form/abilities/validation-ability/index.ts +7 -0
  41. package/src/form/abilities/validation-ability/types.ts +44 -0
  42. package/src/form/abilities/validation-ability/validation-ability.ts +14 -0
  43. package/src/form/abilities/visibility-ability/index.ts +6 -0
  44. package/src/form/abilities/visibility-ability/visibility-ability.ts +25 -0
  45. package/src/form/client/index.ts +17 -0
  46. package/src/form/flow-node-form-data.ts +109 -0
  47. package/src/form/form-contribution.ts +12 -0
  48. package/src/form/form-core-container-module.ts +19 -0
  49. package/src/form/form-node-contribution.ts +16 -0
  50. package/src/form/form-render.ts +13 -0
  51. package/src/form/index.ts +13 -0
  52. package/src/form/models/form-ability-extension-registry.ts +30 -0
  53. package/src/form/models/form-item-ability.ts +18 -0
  54. package/src/form/models/form-item-material-context.ts +50 -0
  55. package/src/form/models/form-item.ts +53 -0
  56. package/src/form/models/form-meta.ts +62 -0
  57. package/src/form/models/form-model.ts +84 -0
  58. package/src/form/models/index.ts +11 -0
  59. package/src/form/services/form-context-maker.ts +35 -0
  60. package/src/form/services/form-manager.ts +113 -0
  61. package/src/form/services/form-path-service.ts +88 -0
  62. package/src/form/services/index.ts +8 -0
  63. package/src/form/types/form-ability.types.ts +65 -0
  64. package/src/form/types/form-meta.types.ts +121 -0
  65. package/src/form/types/form-model.types.ts +33 -0
  66. package/src/form/types/index.ts +8 -0
  67. package/src/index.ts +10 -0
  68. package/src/node/core-materials.ts +9 -0
  69. package/src/node/core-plugins.ts +9 -0
  70. package/src/node/index.ts +13 -0
  71. package/src/node/node-container-module.ts +16 -0
  72. package/src/node/node-contribution.ts +12 -0
  73. package/src/node/node-engine-context.ts +54 -0
  74. package/src/node/node-engine.ts +16 -0
  75. package/src/node/node-manager.ts +63 -0
  76. package/src/node/types.ts +30 -0
  77. package/src/node-vue/composables/index.ts +7 -0
  78. package/src/node-vue/composables/use-form-item.ts +28 -0
  79. package/src/node-vue/composables/use-node-engine-context.ts +25 -0
  80. package/src/node-vue/context/index.ts +6 -0
  81. package/src/node-vue/context/node-engine-vue-context.ts +24 -0
  82. package/src/node-vue/hooks/index.ts +6 -0
  83. package/src/node-vue/index.ts +7 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { injectable } from 'inversify';
7
+
8
+ @injectable()
9
+ export class FormPathService {
10
+ static readonly ROOT = '/';
11
+
12
+ static readonly DIVIDER = '/';
13
+
14
+ static readonly RELATIVE_PARENT = '..';
15
+
16
+ static readonly RELATIVE_CURRENT = '.';
17
+
18
+ static readonly ARRAY = '[]';
19
+
20
+ static normalize(path: string) {
21
+ if (path === FormPathService.ROOT) {
22
+ return path;
23
+ }
24
+ // 去掉末尾的斜杠
25
+ if (path.endsWith(FormPathService.DIVIDER)) {
26
+ path = path.slice(0, -1);
27
+ }
28
+ return path;
29
+ }
30
+
31
+ static join(paths: string[]): string {
32
+ if (paths[1].startsWith(FormPathService.ROOT)) {
33
+ throw new Error(
34
+ `FormPathService Error: join failed, invalid paths[1], paths[1]= ${paths[1]}`,
35
+ );
36
+ }
37
+ if (paths[0].endsWith(FormPathService.DIVIDER)) {
38
+ return `${paths[0]}${paths[1]}`;
39
+ }
40
+ return paths.join(FormPathService.DIVIDER);
41
+ }
42
+
43
+ static toArrayPath(path: string): string {
44
+ return FormPathService.join([path, FormPathService.ARRAY]);
45
+ }
46
+
47
+ static parseArrayItemPath(path: string) {
48
+ const names = path.split('/');
49
+
50
+ let i = 0;
51
+ while (i < names.length) {
52
+ const itemIndex = parseInt(names[i]);
53
+
54
+ if (!isNaN(itemIndex)) {
55
+ const arrayPath = FormPathService.toArrayPath(
56
+ names.slice(0, i).join(FormPathService.DIVIDER),
57
+ );
58
+ const restPath = names.slice(i + 1).join(FormPathService.DIVIDER);
59
+ const itemMetaPath = FormPathService.join([arrayPath, restPath]);
60
+ return { itemIndex, arrayPath, itemMetaPath };
61
+ }
62
+ i = i + 1;
63
+ }
64
+ return null;
65
+ }
66
+
67
+ simplify(path: string) {
68
+ const segments = path.split(FormPathService.DIVIDER);
69
+ const resSegments: string[] = [];
70
+
71
+ for (let i = 0; i < segments.length; i++) {
72
+ if (!segments[i]) {
73
+ throw new Error('FormPathService: join failed');
74
+ }
75
+
76
+ if (segments[i] === FormPathService.RELATIVE_CURRENT) {
77
+ // eslint-disable-next-line no-continue
78
+ continue;
79
+ }
80
+
81
+ if (segments[i] === FormPathService.RELATIVE_PARENT) {
82
+ resSegments.pop();
83
+ }
84
+ resSegments.push(segments[i]);
85
+ }
86
+ return resSegments.join(FormPathService.DIVIDER);
87
+ }
88
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './form-path-service';
7
+ export * from './form-manager';
8
+ export * from './form-context-maker';
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowNodeEntity } from '@flowgram-vue/document';
7
+ import { PlaygroundContext } from '@flowgram-vue/core';
8
+ import { MaybePromise } from '@flowgram-vue/utils';
9
+
10
+ import { type IFormItem } from './form-model.types';
11
+ import { IFormItemMeta } from './form-meta.types';
12
+
13
+ export interface FormItemAbilityMeta<Options = any> {
14
+ type: string;
15
+ options: Options;
16
+ }
17
+
18
+ /**
19
+ * @deprecated
20
+ */
21
+ export interface FormItemContext {
22
+ /**
23
+ * @deprecated Use context.node instead
24
+ */
25
+ formItemMeta: IFormItemMeta;
26
+ /**
27
+ * @deprecated
28
+ */
29
+ formItem: IFormItem;
30
+ /**
31
+ * @deprecated Use context.node instead
32
+ */
33
+ flowNodeEntity: FlowNodeEntity;
34
+ /**
35
+ * @deprecated Use context.playgroundContext instead
36
+ */
37
+ playgroundContext: PlaygroundContext;
38
+ }
39
+
40
+ export interface FormItemHookParams extends FormItemContext {
41
+ formItem: IFormItem;
42
+ }
43
+
44
+ export interface FormItemHooks<T> {
45
+ /**
46
+ * FormItem初始化钩子
47
+ */
48
+ onInit?: (params: FormItemHookParams & T) => void;
49
+ /**
50
+ * FormItem提交时钩子
51
+ */
52
+ onSubmit?: (params: FormItemHookParams & T) => void;
53
+ /**
54
+ * FormItem克隆时钩子
55
+ */
56
+ onClone?: (params: FormItemHookParams & T) => MaybePromise<void>;
57
+ /**
58
+ * 克隆后执行的逻辑
59
+ */
60
+ afterClone?: (params: FormItemHookParams & T) => void;
61
+ /**
62
+ * FormItem全局校验时钩子
63
+ */
64
+ onValidate?: (params: FormItemHookParams & T) => void;
65
+ }
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { MaybePromise } from '@flowgram-vue/utils';
7
+ import { FlowNodeEntity } from '@flowgram-vue/document';
8
+ import { PlaygroundContext, PluginContext } from '@flowgram-vue/core';
9
+
10
+ import { type FormItemAbilityMeta } from './form-ability.types';
11
+
12
+ export type FormDataTypeName =
13
+ | 'string'
14
+ | 'number'
15
+ | 'integer'
16
+ | 'boolean'
17
+ | 'object'
18
+ | 'array'
19
+ | 'null';
20
+
21
+ export type FormDataType =
22
+ | string //
23
+ | number
24
+ | boolean
25
+ | FormDataObject
26
+ | DataArray
27
+ | null;
28
+
29
+ export interface FormDataObject {
30
+ [key: string]: FormDataType;
31
+ }
32
+
33
+ export type DataArray = Array<FormDataType>;
34
+
35
+ export const FORM_VOID = 'form-void' as const;
36
+
37
+ export interface TreeNode<T> {
38
+ name: string;
39
+ children?: TreeNode<T>[];
40
+ }
41
+
42
+ export interface IFormItemMeta extends TreeNode<IFormItemMeta> {
43
+ /**
44
+ * 表单项名称
45
+ */
46
+ name: string;
47
+ /**
48
+ * 数据类型
49
+ */
50
+ type: FormDataTypeName | typeof FORM_VOID;
51
+ /**
52
+ * 枚举值
53
+ */
54
+ enum?: FormDataType[];
55
+ /**
56
+ * 数组类型item的数据类型描述
57
+ */
58
+ items?: IFormItemMeta;
59
+ /**
60
+ * 表单项标题
61
+ */
62
+ title?: string;
63
+ /**
64
+ * 表单项描述
65
+ */
66
+ description?: string;
67
+ /**
68
+ * 表单项默认值
69
+ */
70
+ default?: FormDataType;
71
+ /**
72
+ * 是否必填
73
+ */
74
+ required?: boolean;
75
+ /**
76
+ * 扩展能力
77
+ */
78
+ abilities?: FormItemAbilityMeta[];
79
+
80
+ /**
81
+ * 子表单项
82
+ */
83
+ children?: IFormItemMeta[];
84
+ }
85
+
86
+ export interface IFormMeta {
87
+ /**
88
+ * 表单树结构root
89
+ */
90
+ root?: IFormItemMeta;
91
+ /**
92
+ * 表单全局配置
93
+ */
94
+ options?: IFormMetaOptions;
95
+ }
96
+
97
+ export interface NodeFormContext {
98
+ node: FlowNodeEntity;
99
+ playgroundContext: PlaygroundContext;
100
+ clientContext: PluginContext & Record<string, any>;
101
+ }
102
+
103
+ export interface IFormMetaOptions {
104
+ formatOnInit?: (value: any, context: NodeFormContext) => any;
105
+
106
+ formatOnSubmit?: (value: any, context: NodeFormContext) => any;
107
+
108
+ [key: string]: any;
109
+ }
110
+
111
+ export interface FormMetaGeneratorParams<PlaygroundContext, FormValue = any> {
112
+ node: FlowNodeEntity;
113
+ playgroundContext: PlaygroundContext;
114
+ initialValue?: FormValue;
115
+ }
116
+
117
+ export type FormMetaGenerator<PlaygroundContext = any, FormValue = any> = (
118
+ params: FormMetaGeneratorParams<FormValue, FormValue>
119
+ ) => MaybePromise<IFormMeta>;
120
+
121
+ export type FormMetaOrFormMetaGenerator = FormMetaGenerator | IFormMeta;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export interface IFormItem<T = any> {
7
+ value: T;
8
+ }
9
+
10
+ export enum FormItemEventName {
11
+ onFormValueChange = 'onFormValueChange',
12
+ onFormItemInit = 'onFormItemInit',
13
+ }
14
+
15
+ export type FormModelValid = boolean | null;
16
+
17
+ export type FeedbackStatus = 'error' | 'warning' | 'pending';
18
+ export type FeedbackText = string;
19
+
20
+ export interface FormItemFeedback {
21
+ feedbackStatus?: FeedbackStatus;
22
+ feedbackText?: FeedbackText;
23
+ }
24
+
25
+ export interface FormFeedback {
26
+ feedbackStatus?: FeedbackStatus;
27
+ feedbackText?: FeedbackText;
28
+ path: string;
29
+ }
30
+
31
+ export interface FormItemDomRef {
32
+ current: HTMLElement | null;
33
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './form-model.types';
7
+ export * from './form-meta.types';
8
+ export * from './form-ability.types';
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './node';
7
+ export * from './error';
8
+ export * from './form';
9
+ export * from './client';
10
+ export * from './node-vue';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export const MATERIAL_KEY = {
7
+ NODE_ERROR_RENDER: 'node_error_render',
8
+ NODE_PLACEHOLDER_RENDER: 'node_placeholder_render',
9
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export const PLUGIN_KEY = {
7
+ FORM: 'Plugin_Form',
8
+ ERROR: 'Plugin_Error',
9
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export { NodeContribution } from './node-contribution';
7
+ export * from './node-container-module';
8
+ export * from './node-manager';
9
+ export * from './types';
10
+ export * from './core-plugins';
11
+ export * from './core-materials';
12
+ export * from './node-engine';
13
+ export * from './node-engine-context';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { ContainerModule } from 'inversify';
7
+
8
+ import { NodeManager } from './node-manager';
9
+ import { NodeEngineContext } from './node-engine-context';
10
+ import { NodeEngine } from './node-engine';
11
+
12
+ export const NodeContainerModule = new ContainerModule((bind, unbind, isBound, rebind) => {
13
+ bind(NodeEngine).toSelf().inSingletonScope();
14
+ bind(NodeManager).toSelf().inSingletonScope();
15
+ bind(NodeEngineContext).toSelf().inSingletonScope();
16
+ });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { type NodeManager } from './node-manager';
7
+
8
+ export const NodeContribution = Symbol('NodeContribution');
9
+
10
+ export interface NodeContribution {
11
+ onRegister?(nodeManager: NodeManager): void;
12
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { injectable } from 'inversify';
7
+ import { Emitter } from '@flowgram-vue/utils';
8
+
9
+ export interface INodeEngineContext {
10
+ readonly: boolean;
11
+ }
12
+
13
+ /**
14
+ * NodeEngineContext 在 Node Engine 中为全局单例, 它的作用是让Node之间共享数据。
15
+ * context 分为内置context(如 readonly) 和 自定义context(业务可以按需注入)
16
+ */
17
+ @injectable()
18
+ export class NodeEngineContext {
19
+ static DEFAULT_READONLY = false;
20
+
21
+ static DEFAULT_JSON = { readonly: NodeEngineContext.DEFAULT_READONLY };
22
+
23
+ readonly onChangeEmitter = new Emitter<NodeEngineContext>();
24
+
25
+ readonly onChange = this.onChangeEmitter.event;
26
+
27
+ private _readonly: boolean = NodeEngineContext.DEFAULT_READONLY;
28
+
29
+ private _json: INodeEngineContext = NodeEngineContext.DEFAULT_JSON;
30
+
31
+ get json(): INodeEngineContext {
32
+ return this._json;
33
+ }
34
+
35
+ get readonly(): boolean {
36
+ return this._readonly;
37
+ }
38
+
39
+ set readonly(value: boolean) {
40
+ this._readonly = value;
41
+ this.fireChange();
42
+ }
43
+
44
+ private fireChange(): void {
45
+ this.updateJSON();
46
+ this.onChangeEmitter.fire(this);
47
+ }
48
+
49
+ private updateJSON(): void {
50
+ this._json = {
51
+ readonly: this._readonly,
52
+ };
53
+ }
54
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { injectable, inject } from 'inversify';
7
+
8
+ import { NodeManager } from './node-manager';
9
+ import { NodeEngineContext } from './node-engine-context';
10
+
11
+ @injectable()
12
+ export class NodeEngine {
13
+ @inject(NodeManager) nodeManager: NodeManager;
14
+
15
+ @inject(NodeEngineContext) context: NodeEngineContext;
16
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { flow } from 'lodash-es';
7
+ import { injectable, multiInject, optional, postConstruct } from 'inversify';
8
+
9
+ import { NodeErrorRenderProps } from '../error';
10
+ import { NodePluginRender, NodeRenderHoc, Render } from './types';
11
+ import { NodeContribution } from './node-contribution';
12
+
13
+ export enum MaterialRenderKey {
14
+ CustomNodeError = 'Material_CustomNodeError',
15
+ }
16
+
17
+ @injectable()
18
+ export class NodeManager {
19
+ readonly materialRenderRegistry: Map<string, Render> = new Map();
20
+
21
+ readonly pluginRenderRegistry: Map<string, Render> = new Map();
22
+
23
+ readonly nodeRenderHocs: NodeRenderHoc[] = [];
24
+
25
+ @multiInject(NodeContribution) @optional() protected nodeContributions: NodeContribution[] = [];
26
+
27
+ registerMaterialRender(key: string, render: Render) {
28
+ this.materialRenderRegistry.set(key, render);
29
+ }
30
+
31
+ getMaterialRender(key: string): Render | undefined {
32
+ return this.materialRenderRegistry.get(key);
33
+ }
34
+
35
+ registerPluginRender(key: string, render: NodePluginRender): void {
36
+ this.pluginRenderRegistry.set(key, render);
37
+ }
38
+
39
+ getPluginRender(key: string): NodePluginRender | undefined {
40
+ return this.pluginRenderRegistry.get(key);
41
+ }
42
+
43
+ registerNodeErrorRender(render: Render<NodeErrorRenderProps>) {
44
+ this.registerMaterialRender(MaterialRenderKey.CustomNodeError, render);
45
+ }
46
+
47
+ get nodeRenderHoc() {
48
+ return flow(this.nodeRenderHocs);
49
+ }
50
+
51
+ registerNodeRenderHoc(hoc: NodeRenderHoc) {
52
+ this.nodeRenderHocs.push(hoc);
53
+ }
54
+
55
+ get nodeErrorRender() {
56
+ return this.materialRenderRegistry.get(MaterialRenderKey.CustomNodeError);
57
+ }
58
+
59
+ @postConstruct()
60
+ protected init(): void {
61
+ this.nodeContributions.forEach((contrib) => contrib.onRegister?.(this));
62
+ }
63
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type { Component } from 'vue';
7
+
8
+ import { FlowNodeEntity } from '@flowgram-vue/document';
9
+
10
+ import type { NodeFormContext } from '../form/types/form-meta.types';
11
+
12
+ /**
13
+ * @deprecated
14
+ * use `NodeFormContext` instead
15
+ */
16
+ export type NodeContext = NodeFormContext;
17
+
18
+ export type Render<T = any> = (props: T) => any;
19
+
20
+ export type NodePluginRender = Render<NodeFormContext>;
21
+
22
+ export type NodePlaceholderRender = Render<NodeFormContext>;
23
+
24
+ export interface NodeRenderProps {
25
+ node: FlowNodeEntity;
26
+ }
27
+
28
+ export type NodeRenderHoc = (
29
+ Component: Component<NodeRenderProps> | (() => any)
30
+ ) => Component<NodeRenderProps> | (() => any);
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './use-node-engine-context';
7
+ export * from './use-form-item';
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { onBeforeUnmount } from 'vue';
7
+
8
+ import { FlowNodeEntity } from '@flowgram-vue/document';
9
+ import { useEntityFromContext, useRefresh } from '@flowgram-vue/core';
10
+
11
+ import { FlowNodeFormData, FormModel, IFormItem } from '../../form';
12
+
13
+ export function useFormItem(path: string): IFormItem | undefined {
14
+ const refresh = useRefresh();
15
+ const node = useEntityFromContext<FlowNodeEntity>();
16
+ const formData = node.getData<FlowNodeFormData>(FlowNodeFormData);
17
+ const formItem = formData.getFormModel<FormModel>().getFormItemByPath(path);
18
+
19
+ const disposable = formData.onDataChange(() => {
20
+ refresh();
21
+ });
22
+
23
+ onBeforeUnmount(() => {
24
+ disposable.dispose();
25
+ });
26
+
27
+ return formItem;
28
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { onBeforeUnmount } from 'vue';
7
+
8
+ import { useService, useRefresh } from '@flowgram-vue/core';
9
+
10
+ import { NodeEngineContext } from '../../node';
11
+
12
+ export function useNodeEngineContext(): NodeEngineContext {
13
+ const refresh = useRefresh();
14
+ const nodeEngineContext = useService<NodeEngineContext>(NodeEngineContext);
15
+
16
+ const disposable = nodeEngineContext.onChange(() => {
17
+ refresh();
18
+ });
19
+
20
+ onBeforeUnmount(() => {
21
+ disposable.dispose();
22
+ });
23
+
24
+ return nodeEngineContext;
25
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './node-engine-vue-context';
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type { InjectionKey } from 'vue';
7
+ import { inject, provide } from 'vue';
8
+
9
+ import { INodeEngineContext, NodeEngineContext } from '../../node';
10
+
11
+ export const NodeEngineVueContextKey: InjectionKey<INodeEngineContext> = Symbol(
12
+ 'NodeEngineVueContext'
13
+ );
14
+
15
+ export function provideNodeEngineContext(ctx: INodeEngineContext): void {
16
+ provide(NodeEngineVueContextKey, ctx);
17
+ }
18
+
19
+ export function useNodeEngineVueContext(): INodeEngineContext {
20
+ return inject(NodeEngineVueContextKey, NodeEngineContext.DEFAULT_JSON);
21
+ }
22
+
23
+ /** @deprecated use NodeEngineVueContextKey */
24
+ export const NodeEngineVueContext = NodeEngineVueContextKey;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from '../composables';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './hooks';
7
+ export * from './context';