@flowgram.ai/test-run-plugin 0.1.0-alpha.20
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/.eslintrc.cjs +17 -0
- package/.rush/temp/chunked-rush-logs/test-run-plugin.build.chunks.jsonl +21 -0
- package/.rush/temp/package-deps_build.json +47 -0
- package/.rush/temp/shrinkwrap-deps.json +161 -0
- package/dist/esm/index.js +731 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +314 -0
- package/dist/index.d.ts +314 -0
- package/dist/index.js +770 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
- package/rush-logs/test-run-plugin.build.log +21 -0
- package/src/create-test-run-plugin.ts +39 -0
- package/src/form-engine/contexts.ts +16 -0
- package/src/form-engine/fields/create-field.tsx +32 -0
- package/src/form-engine/fields/general-field.tsx +35 -0
- package/src/form-engine/fields/index.ts +9 -0
- package/src/form-engine/fields/object-field.tsx +21 -0
- package/src/form-engine/fields/reactive-field.tsx +57 -0
- package/src/form-engine/fields/recursion-field.tsx +31 -0
- package/src/form-engine/fields/schema-field.tsx +32 -0
- package/src/form-engine/form/form.tsx +38 -0
- package/src/form-engine/form/index.ts +6 -0
- package/src/form-engine/hooks/index.ts +8 -0
- package/src/form-engine/hooks/use-create-form.ts +69 -0
- package/src/form-engine/hooks/use-field.ts +13 -0
- package/src/form-engine/hooks/use-form.ts +13 -0
- package/src/form-engine/index.ts +19 -0
- package/src/form-engine/model/index.ts +89 -0
- package/src/form-engine/types.ts +56 -0
- package/src/form-engine/utils.ts +64 -0
- package/src/index.ts +22 -0
- package/src/reactive/hooks/index.ts +7 -0
- package/src/reactive/hooks/use-create-form.ts +90 -0
- package/src/reactive/hooks/use-test-run-service.ts +10 -0
- package/src/reactive/index.ts +6 -0
- package/src/services/config.ts +42 -0
- package/src/services/form/factory.ts +9 -0
- package/src/services/form/form.ts +78 -0
- package/src/services/form/index.ts +8 -0
- package/src/services/form/manager.ts +43 -0
- package/src/services/index.ts +14 -0
- package/src/services/pipeline/factory.ts +9 -0
- package/src/services/pipeline/index.ts +12 -0
- package/src/services/pipeline/pipeline.ts +143 -0
- package/src/services/pipeline/plugin.ts +11 -0
- package/src/services/pipeline/tap.ts +34 -0
- package/src/services/store.ts +27 -0
- package/src/services/test-run.ts +100 -0
- package/src/types.ts +29 -0
- package/tsconfig.json +12 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,770 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
30
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
31
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
32
|
+
if (decorator = decorators[i])
|
|
33
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
34
|
+
if (kind && result) __defProp(target, key, result);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
38
|
+
|
|
39
|
+
// src/index.ts
|
|
40
|
+
var index_exports = {};
|
|
41
|
+
__export(index_exports, {
|
|
42
|
+
FormEngine: () => FormEngine,
|
|
43
|
+
TestRunPipelineEntity: () => TestRunPipelineEntity,
|
|
44
|
+
connect: () => connect,
|
|
45
|
+
createTestRunPlugin: () => createTestRunPlugin,
|
|
46
|
+
useCreateForm: () => useCreateForm2,
|
|
47
|
+
useTestRunService: () => useTestRunService
|
|
48
|
+
});
|
|
49
|
+
module.exports = __toCommonJS(index_exports);
|
|
50
|
+
|
|
51
|
+
// src/create-test-run-plugin.ts
|
|
52
|
+
var import_core = require("@flowgram.ai/core");
|
|
53
|
+
|
|
54
|
+
// src/services/form/form.ts
|
|
55
|
+
var import_react10 = require("react");
|
|
56
|
+
var import_nanoid = require("nanoid");
|
|
57
|
+
var import_inversify = require("inversify");
|
|
58
|
+
var import_utils4 = require("@flowgram.ai/utils");
|
|
59
|
+
|
|
60
|
+
// src/services/config.ts
|
|
61
|
+
var TestRunConfig = Symbol("TestRunConfig");
|
|
62
|
+
var defineConfig = (config) => {
|
|
63
|
+
const defaultConfig = {
|
|
64
|
+
components: {},
|
|
65
|
+
nodes: {},
|
|
66
|
+
plugins: []
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
...defaultConfig,
|
|
70
|
+
...config
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// src/form-engine/form/form.tsx
|
|
75
|
+
var import_form3 = require("@flowgram.ai/form");
|
|
76
|
+
|
|
77
|
+
// src/form-engine/hooks/use-create-form.ts
|
|
78
|
+
var import_react2 = require("react");
|
|
79
|
+
var import_form = require("@flowgram.ai/form");
|
|
80
|
+
|
|
81
|
+
// src/form-engine/utils.ts
|
|
82
|
+
var import_react = require("react");
|
|
83
|
+
var getUniqueFieldName = (...args) => args.filter((path) => path).join(".");
|
|
84
|
+
var mergeFieldPath = (path, name) => [...path || [], name].filter((i) => Boolean(i));
|
|
85
|
+
var createValidate = (schema) => {
|
|
86
|
+
const rules = {};
|
|
87
|
+
visit(schema);
|
|
88
|
+
return rules;
|
|
89
|
+
function visit(current, name) {
|
|
90
|
+
if (name && current["x-validator"]) {
|
|
91
|
+
rules[name] = current["x-validator"];
|
|
92
|
+
}
|
|
93
|
+
if (current.type === "object" && current.properties) {
|
|
94
|
+
Object.entries(current.properties).forEach(([key, value]) => {
|
|
95
|
+
visit(value, getUniqueFieldName(name, key));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
var connect = (Component, mapProps) => {
|
|
101
|
+
const Connected = (props) => {
|
|
102
|
+
const mappedProps = mapProps(props);
|
|
103
|
+
return (0, import_react.createElement)(Component, mappedProps, mappedProps.children);
|
|
104
|
+
};
|
|
105
|
+
return Connected;
|
|
106
|
+
};
|
|
107
|
+
var isFormEmpty = (schema) => {
|
|
108
|
+
const isEmpty = (s) => {
|
|
109
|
+
if (!s.type || s.type === "object" || !s.name) {
|
|
110
|
+
return Object.entries(schema.properties || {}).map(([key, value]) => ({
|
|
111
|
+
name: key,
|
|
112
|
+
...value
|
|
113
|
+
})).every(isFormEmpty);
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
};
|
|
117
|
+
return isEmpty(schema);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// src/form-engine/model/index.ts
|
|
121
|
+
var import_reactive = require("@flowgram.ai/reactive");
|
|
122
|
+
var FormSchemaModel = class _FormSchemaModel {
|
|
123
|
+
constructor(json, path = []) {
|
|
124
|
+
this.path = [];
|
|
125
|
+
this.state = new import_reactive.ReactiveState({ disabled: false });
|
|
126
|
+
this.fromJSON(json);
|
|
127
|
+
this.path = path;
|
|
128
|
+
}
|
|
129
|
+
get componentType() {
|
|
130
|
+
return this["x-component"];
|
|
131
|
+
}
|
|
132
|
+
get componentProps() {
|
|
133
|
+
return this["x-component-props"];
|
|
134
|
+
}
|
|
135
|
+
get decoratorType() {
|
|
136
|
+
return this["x-decorator"];
|
|
137
|
+
}
|
|
138
|
+
get decoratorProps() {
|
|
139
|
+
return this["x-decorator-props"];
|
|
140
|
+
}
|
|
141
|
+
get uniqueName() {
|
|
142
|
+
return getUniqueFieldName(...this.path);
|
|
143
|
+
}
|
|
144
|
+
fromJSON(json) {
|
|
145
|
+
Object.entries(json).forEach(([key, value]) => {
|
|
146
|
+
this[key] = value;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
getPropertyList() {
|
|
150
|
+
const orderProperties = [];
|
|
151
|
+
const unOrderProperties = [];
|
|
152
|
+
Object.entries(this.properties || {}).forEach(([key, item]) => {
|
|
153
|
+
const index = item["x-index"];
|
|
154
|
+
const defaultValues = this.defaultValue;
|
|
155
|
+
if (typeof defaultValues === "object" && defaultValues !== null && key in defaultValues) {
|
|
156
|
+
item.defaultValue = defaultValues[key];
|
|
157
|
+
}
|
|
158
|
+
const current = new _FormSchemaModel(item, mergeFieldPath(this.path, key));
|
|
159
|
+
if (index !== void 0 && !isNaN(index)) {
|
|
160
|
+
orderProperties[index] = current;
|
|
161
|
+
} else {
|
|
162
|
+
unOrderProperties.push(current);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
return orderProperties.concat(unOrderProperties).filter((item) => !!item);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// src/form-engine/hooks/use-create-form.ts
|
|
170
|
+
var useCreateForm = (schema, options = {}) => {
|
|
171
|
+
const { form, control } = (0, import_react2.useMemo)(
|
|
172
|
+
() => (0, import_form.createForm)({
|
|
173
|
+
validate: {
|
|
174
|
+
...createValidate(schema),
|
|
175
|
+
...options.validate
|
|
176
|
+
},
|
|
177
|
+
validateTrigger: options.validateTrigger ?? import_form.ValidateTrigger.onBlur
|
|
178
|
+
}),
|
|
179
|
+
[schema]
|
|
180
|
+
);
|
|
181
|
+
const model = (0, import_react2.useMemo)(
|
|
182
|
+
() => new FormSchemaModel({ type: "object", ...schema, defaultValue: options.defaultValues }),
|
|
183
|
+
[schema]
|
|
184
|
+
);
|
|
185
|
+
(0, import_react2.useEffect)(() => {
|
|
186
|
+
if (options.onMounted) {
|
|
187
|
+
options.onMounted({ model, form });
|
|
188
|
+
}
|
|
189
|
+
const disposable = control._formModel.onFormValuesChange((payload) => {
|
|
190
|
+
if (options.onFormValuesChange) {
|
|
191
|
+
options.onFormValuesChange(payload);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
return () => {
|
|
195
|
+
disposable.dispose();
|
|
196
|
+
if (options.onUnmounted) {
|
|
197
|
+
options.onUnmounted();
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}, [control]);
|
|
201
|
+
return {
|
|
202
|
+
form,
|
|
203
|
+
control,
|
|
204
|
+
model
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// src/form-engine/hooks/use-field.ts
|
|
209
|
+
var import_react4 = require("react");
|
|
210
|
+
var import_reactive2 = require("@flowgram.ai/reactive");
|
|
211
|
+
|
|
212
|
+
// src/form-engine/contexts.ts
|
|
213
|
+
var import_react3 = require("react");
|
|
214
|
+
var FieldModelContext = (0, import_react3.createContext)({});
|
|
215
|
+
var FormModelContext = (0, import_react3.createContext)({});
|
|
216
|
+
var ComponentsContext = (0, import_react3.createContext)({});
|
|
217
|
+
|
|
218
|
+
// src/form-engine/hooks/use-field.ts
|
|
219
|
+
var useFieldModel = () => (0, import_react4.useContext)(FieldModelContext);
|
|
220
|
+
var useFieldState = () => (0, import_reactive2.useObserve)(useFieldModel().state.value);
|
|
221
|
+
|
|
222
|
+
// src/form-engine/hooks/use-form.ts
|
|
223
|
+
var import_react5 = require("react");
|
|
224
|
+
var import_reactive3 = require("@flowgram.ai/reactive");
|
|
225
|
+
var useFormModel = () => (0, import_react5.useContext)(FormModelContext);
|
|
226
|
+
var useFormState = () => (0, import_reactive3.useObserve)(useFormModel().state.value);
|
|
227
|
+
|
|
228
|
+
// src/form-engine/fields/schema-field.tsx
|
|
229
|
+
var import_react9 = require("react");
|
|
230
|
+
|
|
231
|
+
// src/form-engine/fields/recursion-field.tsx
|
|
232
|
+
var import_react8 = require("react");
|
|
233
|
+
|
|
234
|
+
// src/form-engine/fields/reactive-field.tsx
|
|
235
|
+
var import_react6 = require("react");
|
|
236
|
+
var import_react7 = __toESM(require("react"));
|
|
237
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
238
|
+
var ReactiveField = (props) => {
|
|
239
|
+
const formState = useFormState();
|
|
240
|
+
const model = useFieldModel();
|
|
241
|
+
const modelState = useFieldState();
|
|
242
|
+
const components = (0, import_react6.useContext)(ComponentsContext);
|
|
243
|
+
const disabled = modelState.disabled || formState.disabled;
|
|
244
|
+
const componentRender = () => {
|
|
245
|
+
if (!model.componentType || !components[model.componentType]) {
|
|
246
|
+
return props.children;
|
|
247
|
+
}
|
|
248
|
+
return import_react7.default.createElement(
|
|
249
|
+
components[model.componentType],
|
|
250
|
+
{
|
|
251
|
+
disabled,
|
|
252
|
+
...model.componentProps,
|
|
253
|
+
...props.componentProps
|
|
254
|
+
},
|
|
255
|
+
props.children
|
|
256
|
+
);
|
|
257
|
+
};
|
|
258
|
+
const decoratorRender = (children) => {
|
|
259
|
+
if (!model.decoratorType || !components[model.decoratorType]) {
|
|
260
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
|
|
261
|
+
}
|
|
262
|
+
return import_react7.default.createElement(
|
|
263
|
+
components[model.decoratorType],
|
|
264
|
+
{
|
|
265
|
+
type: model.type,
|
|
266
|
+
required: model.required,
|
|
267
|
+
...model.decoratorProps,
|
|
268
|
+
...props.decoratorProps
|
|
269
|
+
},
|
|
270
|
+
children
|
|
271
|
+
);
|
|
272
|
+
};
|
|
273
|
+
return decoratorRender(componentRender());
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
// src/form-engine/fields/object-field.tsx
|
|
277
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
278
|
+
var ObjectField = ({
|
|
279
|
+
model,
|
|
280
|
+
children
|
|
281
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FieldModelContext.Provider, { value: model, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReactiveField, { children }) });
|
|
282
|
+
|
|
283
|
+
// src/form-engine/fields/general-field.tsx
|
|
284
|
+
var import_form2 = require("@flowgram.ai/form");
|
|
285
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
286
|
+
var GeneralField = ({ model }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FieldModelContext.Provider, { value: model, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
287
|
+
import_form2.Field,
|
|
288
|
+
{
|
|
289
|
+
name: model.uniqueName,
|
|
290
|
+
defaultValue: model.defaultValue,
|
|
291
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
292
|
+
ReactiveField,
|
|
293
|
+
{
|
|
294
|
+
componentProps: {
|
|
295
|
+
value: field.value,
|
|
296
|
+
onChange: field.onChange,
|
|
297
|
+
onFocus: field.onFocus,
|
|
298
|
+
onBlur: field.onBlur,
|
|
299
|
+
...fieldState
|
|
300
|
+
},
|
|
301
|
+
decoratorProps: fieldState
|
|
302
|
+
}
|
|
303
|
+
)
|
|
304
|
+
}
|
|
305
|
+
) });
|
|
306
|
+
|
|
307
|
+
// src/form-engine/fields/recursion-field.tsx
|
|
308
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
309
|
+
var RecursionField = ({ model }) => {
|
|
310
|
+
const properties = (0, import_react8.useMemo)(() => model.getPropertyList(), [model]);
|
|
311
|
+
if (model.type !== "object") {
|
|
312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GeneralField, { model });
|
|
313
|
+
}
|
|
314
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ObjectField, { model, children: properties.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecursionField, { model: item }, item.uniqueName)) });
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
// src/form-engine/fields/schema-field.tsx
|
|
318
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
319
|
+
var SchemaField = ({
|
|
320
|
+
components,
|
|
321
|
+
model,
|
|
322
|
+
children
|
|
323
|
+
}) => {
|
|
324
|
+
const [innerComponents] = (0, import_react9.useState)(() => components);
|
|
325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ComponentsContext.Provider, { value: innerComponents, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(FormModelContext.Provider, { value: model, children: [
|
|
326
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RecursionField, { model }),
|
|
327
|
+
children
|
|
328
|
+
] }) });
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
// src/form-engine/fields/create-field.tsx
|
|
332
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
333
|
+
var createSchemaField = (options) => {
|
|
334
|
+
const InnerSchemaField = ({
|
|
335
|
+
components,
|
|
336
|
+
...props
|
|
337
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
338
|
+
SchemaField,
|
|
339
|
+
{
|
|
340
|
+
components: {
|
|
341
|
+
...options.components,
|
|
342
|
+
...components
|
|
343
|
+
},
|
|
344
|
+
...props
|
|
345
|
+
}
|
|
346
|
+
);
|
|
347
|
+
return InnerSchemaField;
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
// src/form-engine/form/form.tsx
|
|
351
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
352
|
+
var SchemaField2 = createSchemaField({});
|
|
353
|
+
var FormEngine = ({
|
|
354
|
+
schema,
|
|
355
|
+
components,
|
|
356
|
+
children,
|
|
357
|
+
...props
|
|
358
|
+
}) => {
|
|
359
|
+
const { model, control } = useCreateForm(schema, props);
|
|
360
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_form3.Form, { control, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SchemaField2, { model, components, children }) });
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
// src/services/form/form.ts
|
|
364
|
+
var TestRunFormEntity = class {
|
|
365
|
+
constructor() {
|
|
366
|
+
this.initialized = false;
|
|
367
|
+
this.id = (0, import_nanoid.nanoid)();
|
|
368
|
+
this.form = null;
|
|
369
|
+
this.onFormMountedEmitter = new import_utils4.Emitter();
|
|
370
|
+
this.onFormMounted = this.onFormMountedEmitter.event;
|
|
371
|
+
this.onFormUnmountedEmitter = new import_utils4.Emitter();
|
|
372
|
+
this.onFormUnmounted = this.onFormUnmountedEmitter.event;
|
|
373
|
+
}
|
|
374
|
+
get schema() {
|
|
375
|
+
return this._schema;
|
|
376
|
+
}
|
|
377
|
+
init(options) {
|
|
378
|
+
if (this.initialized) return;
|
|
379
|
+
this._schema = options.schema;
|
|
380
|
+
this.initialized = true;
|
|
381
|
+
}
|
|
382
|
+
render(props) {
|
|
383
|
+
if (!this.initialized) {
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
const { children, ...restProps } = props || {};
|
|
387
|
+
return (0, import_react10.createElement)(
|
|
388
|
+
FormEngine,
|
|
389
|
+
{
|
|
390
|
+
schema: this.schema,
|
|
391
|
+
components: this.config.components,
|
|
392
|
+
onMounted: (instance) => {
|
|
393
|
+
this.form = instance;
|
|
394
|
+
this.onFormMountedEmitter.fire(instance);
|
|
395
|
+
},
|
|
396
|
+
onUnmounted: this.onFormUnmountedEmitter.fire.bind(this.onFormUnmountedEmitter),
|
|
397
|
+
...restProps
|
|
398
|
+
},
|
|
399
|
+
children
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
dispose() {
|
|
403
|
+
this._schema = {};
|
|
404
|
+
this.form = null;
|
|
405
|
+
this.onFormMountedEmitter.dispose();
|
|
406
|
+
this.onFormUnmountedEmitter.dispose();
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
__decorateClass([
|
|
410
|
+
(0, import_inversify.inject)(TestRunConfig)
|
|
411
|
+
], TestRunFormEntity.prototype, "config", 2);
|
|
412
|
+
TestRunFormEntity = __decorateClass([
|
|
413
|
+
(0, import_inversify.injectable)()
|
|
414
|
+
], TestRunFormEntity);
|
|
415
|
+
|
|
416
|
+
// src/services/form/factory.ts
|
|
417
|
+
var TestRunFormFactory = Symbol("TestRunFormFactory");
|
|
418
|
+
|
|
419
|
+
// src/services/form/manager.ts
|
|
420
|
+
var import_inversify2 = require("inversify");
|
|
421
|
+
var TestRunFormManager = class {
|
|
422
|
+
constructor() {
|
|
423
|
+
this.entities = /* @__PURE__ */ new Map();
|
|
424
|
+
}
|
|
425
|
+
createForm() {
|
|
426
|
+
return this.factory();
|
|
427
|
+
}
|
|
428
|
+
getForm(id) {
|
|
429
|
+
return this.entities.get(id);
|
|
430
|
+
}
|
|
431
|
+
getAllForm() {
|
|
432
|
+
return Array.from(this.entities);
|
|
433
|
+
}
|
|
434
|
+
disposeForm(id) {
|
|
435
|
+
const form = this.entities.get(id);
|
|
436
|
+
if (!form) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
form.dispose();
|
|
440
|
+
this.entities.delete(id);
|
|
441
|
+
}
|
|
442
|
+
disposeAllForm() {
|
|
443
|
+
for (const id of this.entities.keys()) {
|
|
444
|
+
this.disposeForm(id);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
__decorateClass([
|
|
449
|
+
(0, import_inversify2.inject)(TestRunFormFactory)
|
|
450
|
+
], TestRunFormManager.prototype, "factory", 2);
|
|
451
|
+
TestRunFormManager = __decorateClass([
|
|
452
|
+
(0, import_inversify2.injectable)()
|
|
453
|
+
], TestRunFormManager);
|
|
454
|
+
|
|
455
|
+
// src/services/test-run.ts
|
|
456
|
+
var import_inversify3 = require("inversify");
|
|
457
|
+
var import_utils5 = require("@flowgram.ai/utils");
|
|
458
|
+
|
|
459
|
+
// src/services/pipeline/factory.ts
|
|
460
|
+
var TestRunPipelineFactory = Symbol("TestRunPipelineFactory");
|
|
461
|
+
|
|
462
|
+
// src/services/test-run.ts
|
|
463
|
+
var TestRunService = class {
|
|
464
|
+
constructor() {
|
|
465
|
+
this.pipelineEntities = /* @__PURE__ */ new Map();
|
|
466
|
+
this.pipelineBindings = /* @__PURE__ */ new Map();
|
|
467
|
+
this.onPipelineProgressEmitter = new import_utils5.Emitter();
|
|
468
|
+
this.onPipelineProgress = this.onPipelineProgressEmitter.event;
|
|
469
|
+
this.onPipelineFinishedEmitter = new import_utils5.Emitter();
|
|
470
|
+
this.onPipelineFinished = this.onPipelineFinishedEmitter.event;
|
|
471
|
+
}
|
|
472
|
+
isEnabled(nodeType) {
|
|
473
|
+
const config = this.config.nodes[nodeType];
|
|
474
|
+
return config && config?.enabled !== false;
|
|
475
|
+
}
|
|
476
|
+
async toSchema(node) {
|
|
477
|
+
const nodeType = node.flowNodeType;
|
|
478
|
+
const config = this.config.nodes[nodeType];
|
|
479
|
+
if (!this.isEnabled(nodeType)) {
|
|
480
|
+
return {};
|
|
481
|
+
}
|
|
482
|
+
const properties = typeof config.properties === "function" ? await config.properties({ node }) : config.properties;
|
|
483
|
+
return {
|
|
484
|
+
type: "object",
|
|
485
|
+
properties
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
createFormWithSchema(schema) {
|
|
489
|
+
const form = this.formManager.createForm();
|
|
490
|
+
form.init({ schema });
|
|
491
|
+
return form;
|
|
492
|
+
}
|
|
493
|
+
async createForm(node) {
|
|
494
|
+
const schema = await this.toSchema(node);
|
|
495
|
+
return this.createFormWithSchema(schema);
|
|
496
|
+
}
|
|
497
|
+
createPipeline(options) {
|
|
498
|
+
const pipeline = this.pipelineFactory();
|
|
499
|
+
this.pipelineEntities.set(pipeline.id, pipeline);
|
|
500
|
+
pipeline.init(options);
|
|
501
|
+
return pipeline;
|
|
502
|
+
}
|
|
503
|
+
connectPipeline(pipeline) {
|
|
504
|
+
if (this.pipelineBindings.get(pipeline.id)) {
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
const disposable = new import_utils5.DisposableCollection(
|
|
508
|
+
pipeline.onProgress(this.onPipelineProgressEmitter.fire.bind(this.onPipelineProgressEmitter)),
|
|
509
|
+
pipeline.onFinished(this.onPipelineFinishedEmitter.fire.bind(this.onPipelineFinishedEmitter))
|
|
510
|
+
);
|
|
511
|
+
this.pipelineBindings.set(pipeline.id, disposable);
|
|
512
|
+
}
|
|
513
|
+
disconnectPipeline(id) {
|
|
514
|
+
if (this.pipelineBindings.has(id)) {
|
|
515
|
+
const disposable = this.pipelineBindings.get(id);
|
|
516
|
+
disposable?.dispose();
|
|
517
|
+
this.pipelineBindings.delete(id);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
disconnectAllPipeline() {
|
|
521
|
+
for (const id of this.pipelineBindings.keys()) {
|
|
522
|
+
this.disconnectPipeline(id);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
__decorateClass([
|
|
527
|
+
(0, import_inversify3.inject)(TestRunConfig)
|
|
528
|
+
], TestRunService.prototype, "config", 2);
|
|
529
|
+
__decorateClass([
|
|
530
|
+
(0, import_inversify3.inject)(TestRunPipelineFactory)
|
|
531
|
+
], TestRunService.prototype, "pipelineFactory", 2);
|
|
532
|
+
__decorateClass([
|
|
533
|
+
(0, import_inversify3.inject)(TestRunFormManager)
|
|
534
|
+
], TestRunService.prototype, "formManager", 2);
|
|
535
|
+
TestRunService = __decorateClass([
|
|
536
|
+
(0, import_inversify3.injectable)()
|
|
537
|
+
], TestRunService);
|
|
538
|
+
|
|
539
|
+
// src/services/pipeline/pipeline.ts
|
|
540
|
+
var import_nanoid2 = require("nanoid");
|
|
541
|
+
var import_inversify5 = require("inversify");
|
|
542
|
+
var import_utils6 = require("@flowgram.ai/utils");
|
|
543
|
+
|
|
544
|
+
// src/services/pipeline/tap.ts
|
|
545
|
+
var Tap = class {
|
|
546
|
+
constructor() {
|
|
547
|
+
this.taps = [];
|
|
548
|
+
this.frozen = false;
|
|
549
|
+
}
|
|
550
|
+
tap(name, fn) {
|
|
551
|
+
this.taps.push({ name, fn });
|
|
552
|
+
}
|
|
553
|
+
async call(ctx) {
|
|
554
|
+
for (const tap of this.taps) {
|
|
555
|
+
if (this.frozen) {
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
await tap.fn(ctx);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
freeze() {
|
|
562
|
+
this.frozen = true;
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
// src/services/store.ts
|
|
567
|
+
var import_vanilla = require("zustand/vanilla");
|
|
568
|
+
var import_inversify4 = require("inversify");
|
|
569
|
+
var StoreService = class {
|
|
570
|
+
get getState() {
|
|
571
|
+
return this.store.getState.bind(this.store);
|
|
572
|
+
}
|
|
573
|
+
get setState() {
|
|
574
|
+
return this.store.setState.bind(this.store);
|
|
575
|
+
}
|
|
576
|
+
constructor(stateCreator) {
|
|
577
|
+
this.store = (0, import_vanilla.createStore)(stateCreator);
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
StoreService = __decorateClass([
|
|
581
|
+
(0, import_inversify4.injectable)(),
|
|
582
|
+
__decorateParam(0, (0, import_inversify4.unmanaged)())
|
|
583
|
+
], StoreService);
|
|
584
|
+
|
|
585
|
+
// src/services/pipeline/pipeline.ts
|
|
586
|
+
var initialState = {
|
|
587
|
+
status: "idle",
|
|
588
|
+
data: {}
|
|
589
|
+
};
|
|
590
|
+
var TestRunPipelineEntity = class extends StoreService {
|
|
591
|
+
constructor() {
|
|
592
|
+
super((set, get) => ({
|
|
593
|
+
...initialState,
|
|
594
|
+
getData: () => get().data || {},
|
|
595
|
+
setData: (next) => set((state) => ({ ...state, data: { ...state.data, ...next } }))
|
|
596
|
+
}));
|
|
597
|
+
this.id = (0, import_nanoid2.nanoid)();
|
|
598
|
+
this.prepare = new Tap();
|
|
599
|
+
this.onProgressEmitter = new import_utils6.Emitter();
|
|
600
|
+
this.onProgress = this.onProgressEmitter.event;
|
|
601
|
+
this.onFinishedEmitter = new import_utils6.Emitter();
|
|
602
|
+
this.onFinished = this.onFinishedEmitter.event;
|
|
603
|
+
}
|
|
604
|
+
get status() {
|
|
605
|
+
return this.getState().status;
|
|
606
|
+
}
|
|
607
|
+
set status(next) {
|
|
608
|
+
this.setState({ status: next });
|
|
609
|
+
}
|
|
610
|
+
init(options) {
|
|
611
|
+
if (!this.container) {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
const { plugins } = options;
|
|
615
|
+
for (const PluginClass of plugins) {
|
|
616
|
+
const plugin = this.container.resolve(PluginClass);
|
|
617
|
+
plugin.apply(this);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
registerExecute(fn) {
|
|
621
|
+
this.execute = fn;
|
|
622
|
+
}
|
|
623
|
+
registerProgress(fn) {
|
|
624
|
+
this.progress = fn;
|
|
625
|
+
}
|
|
626
|
+
async start(options) {
|
|
627
|
+
const { data } = options || {};
|
|
628
|
+
if (this.status !== "idle") {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
this.setState({ data });
|
|
632
|
+
const ctx = {
|
|
633
|
+
id: this.id,
|
|
634
|
+
store: this.store,
|
|
635
|
+
operate: {
|
|
636
|
+
update: this.update.bind(this),
|
|
637
|
+
cancel: this.cancel.bind(this)
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
this.status = "preparing";
|
|
641
|
+
await this.prepare.call(ctx);
|
|
642
|
+
if (this.status !== "preparing") {
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
this.status = "executing";
|
|
646
|
+
if (this.execute) {
|
|
647
|
+
await this.execute(ctx);
|
|
648
|
+
}
|
|
649
|
+
if (this.progress) {
|
|
650
|
+
await this.progress(ctx);
|
|
651
|
+
}
|
|
652
|
+
if (this.status === "executing") {
|
|
653
|
+
this.status = "finished";
|
|
654
|
+
this.onFinishedEmitter.fire(this.getState().result);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
update(result) {
|
|
658
|
+
this.setState({ result });
|
|
659
|
+
this.onProgressEmitter.fire(result);
|
|
660
|
+
}
|
|
661
|
+
cancel() {
|
|
662
|
+
if (this.status = "preparing") {
|
|
663
|
+
this.prepare.freeze();
|
|
664
|
+
}
|
|
665
|
+
this.status = "canceled";
|
|
666
|
+
}
|
|
667
|
+
dispose() {
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
TestRunPipelineEntity = __decorateClass([
|
|
671
|
+
(0, import_inversify5.injectable)()
|
|
672
|
+
], TestRunPipelineEntity);
|
|
673
|
+
|
|
674
|
+
// src/create-test-run-plugin.ts
|
|
675
|
+
var createTestRunPlugin = (0, import_core.definePluginCreator)({
|
|
676
|
+
onBind: ({ bind }, opt) => {
|
|
677
|
+
bind(TestRunService).toSelf().inSingletonScope();
|
|
678
|
+
bind(TestRunConfig).toConstantValue(defineConfig(opt));
|
|
679
|
+
bind(TestRunFormManager).toSelf().inSingletonScope();
|
|
680
|
+
bind(TestRunFormFactory).toFactory((context) => () => {
|
|
681
|
+
const e = context.container.resolve(TestRunFormEntity);
|
|
682
|
+
return e;
|
|
683
|
+
});
|
|
684
|
+
bind(TestRunPipelineFactory).toFactory(
|
|
685
|
+
(context) => () => {
|
|
686
|
+
const e = context.container.resolve(TestRunPipelineEntity);
|
|
687
|
+
e.container = context.container.createChild();
|
|
688
|
+
return e;
|
|
689
|
+
}
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
// src/reactive/hooks/use-create-form.ts
|
|
695
|
+
var import_react11 = require("react");
|
|
696
|
+
var import_utils7 = require("@flowgram.ai/utils");
|
|
697
|
+
|
|
698
|
+
// src/reactive/hooks/use-test-run-service.ts
|
|
699
|
+
var import_core2 = require("@flowgram.ai/core");
|
|
700
|
+
var useTestRunService = () => (0, import_core2.useService)(TestRunService);
|
|
701
|
+
|
|
702
|
+
// src/reactive/hooks/use-create-form.ts
|
|
703
|
+
var useCreateForm2 = ({
|
|
704
|
+
node,
|
|
705
|
+
loadingRenderer,
|
|
706
|
+
emptyRenderer,
|
|
707
|
+
defaultValues,
|
|
708
|
+
onMounted,
|
|
709
|
+
onUnmounted,
|
|
710
|
+
onFormValuesChange
|
|
711
|
+
}) => {
|
|
712
|
+
const testRun = useTestRunService();
|
|
713
|
+
const [loading, setLoading] = (0, import_react11.useState)(false);
|
|
714
|
+
const [form, setForm] = (0, import_react11.useState)(null);
|
|
715
|
+
const renderer = (0, import_react11.useMemo)(() => {
|
|
716
|
+
if (loading || !form) {
|
|
717
|
+
return loadingRenderer;
|
|
718
|
+
}
|
|
719
|
+
const isEmpty = isFormEmpty(form.schema);
|
|
720
|
+
return form.render({
|
|
721
|
+
defaultValues,
|
|
722
|
+
onFormValuesChange,
|
|
723
|
+
children: isEmpty ? emptyRenderer : null
|
|
724
|
+
});
|
|
725
|
+
}, [form, loading]);
|
|
726
|
+
const compute = async () => {
|
|
727
|
+
if (!node) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
try {
|
|
731
|
+
setLoading(true);
|
|
732
|
+
const formEntity = await testRun.createForm(node);
|
|
733
|
+
setForm(formEntity);
|
|
734
|
+
} finally {
|
|
735
|
+
setLoading(false);
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
(0, import_react11.useEffect)(() => {
|
|
739
|
+
compute();
|
|
740
|
+
}, [node]);
|
|
741
|
+
(0, import_react11.useEffect)(() => {
|
|
742
|
+
if (!form) {
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
const disposable = new import_utils7.DisposableCollection(
|
|
746
|
+
form.onFormMounted((data) => {
|
|
747
|
+
onMounted?.(data);
|
|
748
|
+
}),
|
|
749
|
+
form.onFormUnmounted(() => {
|
|
750
|
+
onUnmounted?.();
|
|
751
|
+
})
|
|
752
|
+
);
|
|
753
|
+
return () => disposable.dispose();
|
|
754
|
+
}, [form]);
|
|
755
|
+
return {
|
|
756
|
+
renderer,
|
|
757
|
+
loading,
|
|
758
|
+
form
|
|
759
|
+
};
|
|
760
|
+
};
|
|
761
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
762
|
+
0 && (module.exports = {
|
|
763
|
+
FormEngine,
|
|
764
|
+
TestRunPipelineEntity,
|
|
765
|
+
connect,
|
|
766
|
+
createTestRunPlugin,
|
|
767
|
+
useCreateForm,
|
|
768
|
+
useTestRunService
|
|
769
|
+
});
|
|
770
|
+
//# sourceMappingURL=index.js.map
|