@pisell/materials 6.12.39 → 6.12.41
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/build/lowcode/assets-daily.json +11 -11
- package/build/lowcode/assets-dev.json +2 -2
- package/build/lowcode/assets-prod.json +11 -11
- package/build/lowcode/meta.js +1 -1
- package/build/lowcode/render/default/view.js +32 -32
- package/build/lowcode/view.js +32 -32
- package/es/components/PisellSelectionFlow/PisellSelectionFlow.d.ts +7 -0
- package/es/components/PisellSelectionFlow/PisellSelectionFlow.js +392 -0
- package/es/components/PisellSelectionFlow/compiler.d.ts +12 -0
- package/es/components/PisellSelectionFlow/compiler.js +174 -0
- package/es/components/PisellSelectionFlow/context.d.ts +9 -0
- package/es/components/PisellSelectionFlow/context.js +12 -0
- package/es/components/PisellSelectionFlow/hooks/useFlowDraft.js +35 -0
- package/es/components/PisellSelectionFlow/hooks/useFlowModuleLifecycle.js +236 -0
- package/es/components/PisellSelectionFlow/hooks/useFlowNavigation.js +320 -0
- package/es/components/PisellSelectionFlow/index.d.ts +4 -0
- package/es/components/PisellSelectionFlow/types.d.ts +179 -0
- package/es/components/PisellSelectionFlow/types.js +10 -0
- package/es/components/PisellSelectionFlow/utils.js +15 -0
- package/es/index.d.ts +13 -9
- package/es/index.js +5 -1
- package/lib/components/PisellSelectionFlow/PisellSelectionFlow.d.ts +7 -0
- package/lib/components/PisellSelectionFlow/PisellSelectionFlow.js +394 -0
- package/lib/components/PisellSelectionFlow/compiler.d.ts +12 -0
- package/lib/components/PisellSelectionFlow/compiler.js +178 -0
- package/lib/components/PisellSelectionFlow/context.d.ts +9 -0
- package/lib/components/PisellSelectionFlow/context.js +16 -0
- package/lib/components/PisellSelectionFlow/hooks/useFlowDraft.js +36 -0
- package/lib/components/PisellSelectionFlow/hooks/useFlowModuleLifecycle.js +237 -0
- package/lib/components/PisellSelectionFlow/hooks/useFlowNavigation.js +321 -0
- package/lib/components/PisellSelectionFlow/index.d.ts +4 -0
- package/lib/components/PisellSelectionFlow/types.d.ts +179 -0
- package/lib/components/PisellSelectionFlow/types.js +10 -0
- package/lib/components/PisellSelectionFlow/utils.js +18 -0
- package/lib/index.d.ts +13 -9
- package/lib/index.js +15 -2
- package/package.json +1 -1
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
const require_runtime = require("../../_virtual/_rolldown/runtime.js");
|
|
2
|
+
const require_objectSpread2 = require("../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
|
|
3
|
+
const require_types = require("./types.js");
|
|
4
|
+
const require_compiler = require("./compiler.js");
|
|
5
|
+
const require_context = require("./context.js");
|
|
6
|
+
const require_useFlowDraft = require("./hooks/useFlowDraft.js");
|
|
7
|
+
const require_utils = require("./utils.js");
|
|
8
|
+
const require_useFlowModuleLifecycle = require("./hooks/useFlowModuleLifecycle.js");
|
|
9
|
+
const require_useFlowNavigation = require("./hooks/useFlowNavigation.js");
|
|
10
|
+
let react = require("react");
|
|
11
|
+
react = require_runtime.__toESM(react);
|
|
12
|
+
//#region src/components/PisellSelectionFlow/PisellSelectionFlow.tsx
|
|
13
|
+
const createUnexpectedCompileError = (error) => {
|
|
14
|
+
return new require_types.SelectionFlowCompileError([{
|
|
15
|
+
code: "APPLICABILITY_CHECK_FAILED",
|
|
16
|
+
message: `Selection flow compilation failed: ${require_utils.getSelectionFlowErrorMessage(error)}`
|
|
17
|
+
}]);
|
|
18
|
+
};
|
|
19
|
+
const SelectionFlow = ({ registry, draftAdapter, steps, initialDraft, initialStepIndex = 0, hostContext, services, children, onDraftChange, onStepChange, onCompiledStepsChange, onValidationFailed, onConfigurationError, onComplete }, ref) => {
|
|
20
|
+
const mountedRef = (0, react.useRef)(true);
|
|
21
|
+
const flowGenerationRef = (0, react.useRef)(0);
|
|
22
|
+
const draftRevisionRef = (0, react.useRef)(0);
|
|
23
|
+
const navigationRevisionRef = (0, react.useRef)(0);
|
|
24
|
+
const transitionPendingRef = (0, react.useRef)(false);
|
|
25
|
+
const processDraftChangeRef = (0, react.useRef)(() => void 0);
|
|
26
|
+
const onDraftChangeRef = (0, react.useRef)(onDraftChange);
|
|
27
|
+
onDraftChangeRef.current = onDraftChange;
|
|
28
|
+
const onCompleteRef = (0, react.useRef)(onComplete);
|
|
29
|
+
onCompleteRef.current = onComplete;
|
|
30
|
+
const { draft, draftRef, updateDraft } = require_useFlowDraft.useFlowDraft({
|
|
31
|
+
initialDraft,
|
|
32
|
+
draftAdapter,
|
|
33
|
+
mountedRef,
|
|
34
|
+
draftRevisionRef,
|
|
35
|
+
onDraftChangeRef,
|
|
36
|
+
processDraftChangeRef
|
|
37
|
+
});
|
|
38
|
+
const initialDraftRef = (0, react.useRef)(initialDraft);
|
|
39
|
+
const [moduleState, setModuleStateMap] = (0, react.useState)({});
|
|
40
|
+
const moduleStateRef = (0, react.useRef)(moduleState);
|
|
41
|
+
moduleStateRef.current = moduleState;
|
|
42
|
+
const [moduleData, setModuleDataMap] = (0, react.useState)({});
|
|
43
|
+
const moduleDataRef = (0, react.useRef)(moduleData);
|
|
44
|
+
moduleDataRef.current = moduleData;
|
|
45
|
+
const [currentStepIndex, setCurrentStepIndex] = (0, react.useState)(() => Math.max(0, initialStepIndex));
|
|
46
|
+
const currentStepIndexRef = (0, react.useRef)(currentStepIndex);
|
|
47
|
+
currentStepIndexRef.current = currentStepIndex;
|
|
48
|
+
const currentStepKeyRef = (0, react.useRef)();
|
|
49
|
+
const [isCompleting, setIsCompleting] = (0, react.useState)(false);
|
|
50
|
+
const isCompletingRef = (0, react.useRef)(isCompleting);
|
|
51
|
+
isCompletingRef.current = isCompleting;
|
|
52
|
+
const [completionError, setCompletionError] = (0, react.useState)();
|
|
53
|
+
const [completionReason, setCompletionReason] = (0, react.useState)();
|
|
54
|
+
const completedRef = (0, react.useRef)(false);
|
|
55
|
+
const completionPromiseRef = (0, react.useRef)(null);
|
|
56
|
+
const validatedCompletionRef = (0, react.useRef)(null);
|
|
57
|
+
const moduleHandlesRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
58
|
+
const activeModuleKeysRef = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
59
|
+
const moduleRevisionRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
60
|
+
const moduleInitializationRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
61
|
+
const moduleDependencyLifecycleRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
62
|
+
const pendingModuleChangeRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
63
|
+
const compiledStepsRef = (0, react.useRef)([]);
|
|
64
|
+
const configurationErrorRef = (0, react.useRef)(null);
|
|
65
|
+
const contextRef = (0, react.useRef)(null);
|
|
66
|
+
const notifiedStepRef = (0, react.useRef)();
|
|
67
|
+
const notifiedCompiledStepsRef = (0, react.useRef)();
|
|
68
|
+
const createRuntimeIssue = (0, react.useCallback)((code, params) => ({
|
|
69
|
+
code,
|
|
70
|
+
params
|
|
71
|
+
}), []);
|
|
72
|
+
(0, react.useEffect)(() => {
|
|
73
|
+
const generation = flowGenerationRef.current + 1;
|
|
74
|
+
flowGenerationRef.current = generation;
|
|
75
|
+
mountedRef.current = true;
|
|
76
|
+
if (generation > 1) {
|
|
77
|
+
const nextModuleState = Object.fromEntries(Object.keys(moduleStateRef.current).map((moduleKey) => [moduleKey, { status: "idle" }]));
|
|
78
|
+
moduleStateRef.current = nextModuleState;
|
|
79
|
+
moduleDataRef.current = {};
|
|
80
|
+
setModuleStateMap(nextModuleState);
|
|
81
|
+
setModuleDataMap({});
|
|
82
|
+
}
|
|
83
|
+
return () => {
|
|
84
|
+
mountedRef.current = false;
|
|
85
|
+
if (flowGenerationRef.current === generation) flowGenerationRef.current += 1;
|
|
86
|
+
navigationRevisionRef.current += 1;
|
|
87
|
+
moduleInitializationRef.current.clear();
|
|
88
|
+
moduleDependencyLifecycleRef.current.clear();
|
|
89
|
+
pendingModuleChangeRef.current.clear();
|
|
90
|
+
moduleHandlesRef.current.clear();
|
|
91
|
+
};
|
|
92
|
+
}, []);
|
|
93
|
+
const commitModuleState = (0, react.useCallback)((moduleKey, nextState) => {
|
|
94
|
+
if (!mountedRef.current) return;
|
|
95
|
+
const previous = moduleStateRef.current[moduleKey];
|
|
96
|
+
if ((previous === null || previous === void 0 ? void 0 : previous.status) === nextState.status && (previous === null || previous === void 0 ? void 0 : previous.message) === nextState.message && (previous === null || previous === void 0 ? void 0 : previous.reason) === nextState.reason && (previous === null || previous === void 0 ? void 0 : previous.error) === nextState.error) return;
|
|
97
|
+
const nextMap = require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, moduleStateRef.current), {}, { [moduleKey]: nextState });
|
|
98
|
+
moduleStateRef.current = nextMap;
|
|
99
|
+
setModuleStateMap(nextMap);
|
|
100
|
+
}, []);
|
|
101
|
+
const setModuleStatus = (0, react.useCallback)((moduleKey, status, message, error) => {
|
|
102
|
+
commitModuleState(moduleKey, {
|
|
103
|
+
status,
|
|
104
|
+
message,
|
|
105
|
+
error
|
|
106
|
+
});
|
|
107
|
+
}, [commitModuleState]);
|
|
108
|
+
const setModuleData = (0, react.useCallback)((moduleKey, value) => {
|
|
109
|
+
if (!mountedRef.current) return;
|
|
110
|
+
const nextMap = require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, moduleDataRef.current), {}, { [moduleKey]: value });
|
|
111
|
+
moduleDataRef.current = nextMap;
|
|
112
|
+
setModuleDataMap(nextMap);
|
|
113
|
+
}, []);
|
|
114
|
+
const clearModuleData = (0, react.useCallback)((moduleKey) => {
|
|
115
|
+
if (!mountedRef.current) return;
|
|
116
|
+
if (!(moduleKey in moduleDataRef.current)) return;
|
|
117
|
+
const nextMap = require_objectSpread2._objectSpread2({}, moduleDataRef.current);
|
|
118
|
+
delete nextMap[moduleKey];
|
|
119
|
+
moduleDataRef.current = nextMap;
|
|
120
|
+
setModuleDataMap(nextMap);
|
|
121
|
+
}, []);
|
|
122
|
+
const provisionalContext = (0, react.useMemo)(() => ({
|
|
123
|
+
draft,
|
|
124
|
+
updateDraft,
|
|
125
|
+
moduleState,
|
|
126
|
+
setModuleState: commitModuleState,
|
|
127
|
+
setModuleStatus,
|
|
128
|
+
moduleData,
|
|
129
|
+
getModuleData: (moduleKey) => moduleDataRef.current[moduleKey],
|
|
130
|
+
setModuleData,
|
|
131
|
+
clearModuleData,
|
|
132
|
+
steps: [],
|
|
133
|
+
currentStepIndex,
|
|
134
|
+
currentStep: void 0,
|
|
135
|
+
hostContext,
|
|
136
|
+
services
|
|
137
|
+
}), [
|
|
138
|
+
hostContext,
|
|
139
|
+
clearModuleData,
|
|
140
|
+
commitModuleState,
|
|
141
|
+
currentStepIndex,
|
|
142
|
+
draft,
|
|
143
|
+
moduleData,
|
|
144
|
+
moduleState,
|
|
145
|
+
services,
|
|
146
|
+
setModuleData,
|
|
147
|
+
setModuleStatus,
|
|
148
|
+
updateDraft
|
|
149
|
+
]);
|
|
150
|
+
const compilation = (0, react.useMemo)(() => {
|
|
151
|
+
try {
|
|
152
|
+
return {
|
|
153
|
+
steps: require_compiler.compileSelectionFlowSteps(steps, provisionalContext, initialDraftRef.current, registry, draftAdapter),
|
|
154
|
+
error: null
|
|
155
|
+
};
|
|
156
|
+
} catch (error) {
|
|
157
|
+
return {
|
|
158
|
+
steps: [],
|
|
159
|
+
error: error instanceof require_types.SelectionFlowCompileError ? error : createUnexpectedCompileError(error)
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}, [
|
|
163
|
+
draft,
|
|
164
|
+
draftAdapter,
|
|
165
|
+
hostContext,
|
|
166
|
+
registry,
|
|
167
|
+
services,
|
|
168
|
+
steps
|
|
169
|
+
]);
|
|
170
|
+
const compiledSteps = compilation.steps;
|
|
171
|
+
const configurationError = compilation.error;
|
|
172
|
+
compiledStepsRef.current = compiledSteps;
|
|
173
|
+
configurationErrorRef.current = configurationError;
|
|
174
|
+
let resolvedCurrentStepIndex = Math.min(Math.max(0, currentStepIndex), Math.max(0, compiledSteps.length - 1));
|
|
175
|
+
if (currentStepKeyRef.current) {
|
|
176
|
+
const trackedIndex = compiledSteps.findIndex((step) => step.key === currentStepKeyRef.current);
|
|
177
|
+
if (trackedIndex >= 0) resolvedCurrentStepIndex = trackedIndex;
|
|
178
|
+
else if (compiledSteps.length > 0) {
|
|
179
|
+
const firstReviewIndex = compiledSteps.findIndex((step) => step.modules.some((module) => {
|
|
180
|
+
var _moduleStateRef$curre;
|
|
181
|
+
return ((_moduleStateRef$curre = moduleStateRef.current[module.key]) === null || _moduleStateRef$curre === void 0 ? void 0 : _moduleStateRef$curre.status) !== "ready";
|
|
182
|
+
}));
|
|
183
|
+
resolvedCurrentStepIndex = firstReviewIndex >= 0 ? firstReviewIndex : resolvedCurrentStepIndex;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const currentStep = compiledSteps[resolvedCurrentStepIndex];
|
|
187
|
+
currentStepIndexRef.current = resolvedCurrentStepIndex;
|
|
188
|
+
currentStepKeyRef.current = currentStep === null || currentStep === void 0 ? void 0 : currentStep.key;
|
|
189
|
+
const contextValue = (0, react.useMemo)(() => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, provisionalContext), {}, {
|
|
190
|
+
steps: compiledSteps,
|
|
191
|
+
currentStepIndex: resolvedCurrentStepIndex,
|
|
192
|
+
currentStep
|
|
193
|
+
}), [
|
|
194
|
+
compiledSteps,
|
|
195
|
+
currentStep,
|
|
196
|
+
provisionalContext,
|
|
197
|
+
resolvedCurrentStepIndex
|
|
198
|
+
]);
|
|
199
|
+
contextRef.current = contextValue;
|
|
200
|
+
const getFreshContext = (0, react.useCallback)(() => {
|
|
201
|
+
const current = contextRef.current;
|
|
202
|
+
if (!mountedRef.current || !current) return null;
|
|
203
|
+
return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, current), {}, {
|
|
204
|
+
draft: draftRef.current,
|
|
205
|
+
moduleState: moduleStateRef.current,
|
|
206
|
+
moduleData: moduleDataRef.current
|
|
207
|
+
});
|
|
208
|
+
}, []);
|
|
209
|
+
(0, react.useEffect)(() => {
|
|
210
|
+
if (!configurationError) return;
|
|
211
|
+
onConfigurationError === null || onConfigurationError === void 0 || onConfigurationError(configurationError);
|
|
212
|
+
}, [configurationError, onConfigurationError]);
|
|
213
|
+
(0, react.useEffect)(() => {
|
|
214
|
+
if (configurationError) return;
|
|
215
|
+
const fingerprint = require_utils.getCompiledStepsFingerprint(compiledSteps);
|
|
216
|
+
if (notifiedCompiledStepsRef.current === fingerprint) return;
|
|
217
|
+
notifiedCompiledStepsRef.current = fingerprint;
|
|
218
|
+
onCompiledStepsChange === null || onCompiledStepsChange === void 0 || onCompiledStepsChange(compiledSteps);
|
|
219
|
+
}, [
|
|
220
|
+
compiledSteps,
|
|
221
|
+
configurationError,
|
|
222
|
+
onCompiledStepsChange
|
|
223
|
+
]);
|
|
224
|
+
(0, react.useEffect)(() => {
|
|
225
|
+
if (currentStepIndex === resolvedCurrentStepIndex) return;
|
|
226
|
+
setCurrentStepIndex(resolvedCurrentStepIndex);
|
|
227
|
+
}, [currentStepIndex, resolvedCurrentStepIndex]);
|
|
228
|
+
(0, react.useEffect)(() => {
|
|
229
|
+
if (!currentStep) return;
|
|
230
|
+
const notificationKey = `${resolvedCurrentStepIndex}:${currentStep.key}`;
|
|
231
|
+
if (notifiedStepRef.current === notificationKey) return;
|
|
232
|
+
notifiedStepRef.current = notificationKey;
|
|
233
|
+
onStepChange === null || onStepChange === void 0 || onStepChange(resolvedCurrentStepIndex, currentStep);
|
|
234
|
+
}, [
|
|
235
|
+
currentStep,
|
|
236
|
+
onStepChange,
|
|
237
|
+
resolvedCurrentStepIndex
|
|
238
|
+
]);
|
|
239
|
+
(0, react.useEffect)(() => {
|
|
240
|
+
const nextMap = require_objectSpread2._objectSpread2({}, moduleStateRef.current);
|
|
241
|
+
const nextDataMap = require_objectSpread2._objectSpread2({}, moduleDataRef.current);
|
|
242
|
+
const nextActiveKeys = /* @__PURE__ */ new Set();
|
|
243
|
+
let changed = false;
|
|
244
|
+
let dataChanged = false;
|
|
245
|
+
for (const step of compiledSteps) for (const module of step.modules) {
|
|
246
|
+
nextActiveKeys.add(module.key);
|
|
247
|
+
if (!nextMap[module.key]) {
|
|
248
|
+
nextMap[module.key] = { status: "idle" };
|
|
249
|
+
changed = true;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
activeModuleKeysRef.current.forEach((moduleKey) => {
|
|
253
|
+
if (nextActiveKeys.has(moduleKey)) return;
|
|
254
|
+
moduleRevisionRef.current.set(moduleKey, (moduleRevisionRef.current.get(moduleKey) || 0) + 1);
|
|
255
|
+
moduleInitializationRef.current.delete(moduleKey);
|
|
256
|
+
moduleDependencyLifecycleRef.current.delete(moduleKey);
|
|
257
|
+
pendingModuleChangeRef.current.delete(moduleKey);
|
|
258
|
+
moduleHandlesRef.current.delete(moduleKey);
|
|
259
|
+
if (moduleKey in nextMap) {
|
|
260
|
+
delete nextMap[moduleKey];
|
|
261
|
+
changed = true;
|
|
262
|
+
}
|
|
263
|
+
if (moduleKey in nextDataMap) {
|
|
264
|
+
delete nextDataMap[moduleKey];
|
|
265
|
+
dataChanged = true;
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
activeModuleKeysRef.current = nextActiveKeys;
|
|
269
|
+
if (changed) {
|
|
270
|
+
moduleStateRef.current = nextMap;
|
|
271
|
+
setModuleStateMap(nextMap);
|
|
272
|
+
}
|
|
273
|
+
if (dataChanged) {
|
|
274
|
+
moduleDataRef.current = nextDataMap;
|
|
275
|
+
setModuleDataMap(nextDataMap);
|
|
276
|
+
}
|
|
277
|
+
}, [compiledSteps]);
|
|
278
|
+
const { ensureModuleReady } = require_useFlowModuleLifecycle.useFlowModuleLifecycle({
|
|
279
|
+
registry,
|
|
280
|
+
draftAdapter,
|
|
281
|
+
createRuntimeIssue,
|
|
282
|
+
mountedRef,
|
|
283
|
+
flowGenerationRef,
|
|
284
|
+
draftRevisionRef,
|
|
285
|
+
draftRef,
|
|
286
|
+
moduleRevisionRef,
|
|
287
|
+
moduleInitializationRef,
|
|
288
|
+
moduleDependencyLifecycleRef,
|
|
289
|
+
pendingModuleChangeRef,
|
|
290
|
+
compiledStepsRef,
|
|
291
|
+
moduleStateRef,
|
|
292
|
+
processDraftChangeRef,
|
|
293
|
+
commitModuleState,
|
|
294
|
+
getFreshContext,
|
|
295
|
+
currentStep,
|
|
296
|
+
configurationError,
|
|
297
|
+
compiledSteps,
|
|
298
|
+
resolvedCurrentStepIndex,
|
|
299
|
+
draft,
|
|
300
|
+
moduleState
|
|
301
|
+
});
|
|
302
|
+
const { validateCurrentStep, complete, next, back } = require_useFlowNavigation.useFlowNavigation({
|
|
303
|
+
registry,
|
|
304
|
+
draftAdapter,
|
|
305
|
+
createRuntimeIssue,
|
|
306
|
+
mountedRef,
|
|
307
|
+
moduleStateRef,
|
|
308
|
+
moduleRevisionRef,
|
|
309
|
+
draftRevisionRef,
|
|
310
|
+
flowGenerationRef,
|
|
311
|
+
moduleHandlesRef,
|
|
312
|
+
configurationErrorRef,
|
|
313
|
+
compiledStepsRef,
|
|
314
|
+
currentStepIndexRef,
|
|
315
|
+
currentStepKeyRef,
|
|
316
|
+
validatedCompletionRef,
|
|
317
|
+
navigationRevisionRef,
|
|
318
|
+
transitionPendingRef,
|
|
319
|
+
completedRef,
|
|
320
|
+
completionPromiseRef,
|
|
321
|
+
isCompletingRef,
|
|
322
|
+
draftRef,
|
|
323
|
+
onCompleteRef,
|
|
324
|
+
ensureModuleReady,
|
|
325
|
+
commitModuleState,
|
|
326
|
+
getFreshContext,
|
|
327
|
+
onValidationFailed,
|
|
328
|
+
setCurrentStepIndex,
|
|
329
|
+
setCompletionError,
|
|
330
|
+
setCompletionReason,
|
|
331
|
+
setIsCompleting
|
|
332
|
+
});
|
|
333
|
+
const getState = (0, react.useCallback)(() => {
|
|
334
|
+
const stepIndex = currentStepIndexRef.current;
|
|
335
|
+
return {
|
|
336
|
+
draft: draftRef.current,
|
|
337
|
+
currentStepIndex: stepIndex,
|
|
338
|
+
currentStep: compiledStepsRef.current[stepIndex],
|
|
339
|
+
steps: compiledStepsRef.current,
|
|
340
|
+
moduleState: moduleStateRef.current,
|
|
341
|
+
moduleData: moduleDataRef.current,
|
|
342
|
+
isCompleting: isCompletingRef.current,
|
|
343
|
+
isCompleted: completedRef.current,
|
|
344
|
+
configurationError: configurationErrorRef.current
|
|
345
|
+
};
|
|
346
|
+
}, []);
|
|
347
|
+
(0, react.useImperativeHandle)(ref, () => ({
|
|
348
|
+
next,
|
|
349
|
+
back,
|
|
350
|
+
updateDraft,
|
|
351
|
+
validateCurrentStep,
|
|
352
|
+
complete,
|
|
353
|
+
getState
|
|
354
|
+
}), [
|
|
355
|
+
back,
|
|
356
|
+
complete,
|
|
357
|
+
getState,
|
|
358
|
+
next,
|
|
359
|
+
updateDraft,
|
|
360
|
+
validateCurrentStep
|
|
361
|
+
]);
|
|
362
|
+
const registerModuleHandle = (0, react.useCallback)((moduleKey, handle) => {
|
|
363
|
+
if (handle) moduleHandlesRef.current.set(moduleKey, handle);
|
|
364
|
+
else moduleHandlesRef.current.delete(moduleKey);
|
|
365
|
+
}, []);
|
|
366
|
+
const getModuleHandle = (0, react.useCallback)((moduleKey) => moduleHandlesRef.current.get(moduleKey), []);
|
|
367
|
+
const controller = {
|
|
368
|
+
draft,
|
|
369
|
+
currentStepIndex: resolvedCurrentStepIndex,
|
|
370
|
+
currentStep,
|
|
371
|
+
steps: compiledSteps,
|
|
372
|
+
moduleState,
|
|
373
|
+
moduleData,
|
|
374
|
+
isCompleting,
|
|
375
|
+
isCompleted: completedRef.current,
|
|
376
|
+
configurationError,
|
|
377
|
+
completionError,
|
|
378
|
+
completionReason,
|
|
379
|
+
context: contextValue,
|
|
380
|
+
updateDraft,
|
|
381
|
+
validateCurrentStep,
|
|
382
|
+
complete,
|
|
383
|
+
next,
|
|
384
|
+
back,
|
|
385
|
+
getState,
|
|
386
|
+
registerModuleHandle,
|
|
387
|
+
getModuleHandle
|
|
388
|
+
};
|
|
389
|
+
return /* @__PURE__ */ react.default.createElement(require_context.SelectionFlowProvider, { value: contextValue }, children(controller));
|
|
390
|
+
};
|
|
391
|
+
const ForwardedSelectionFlow = (0, react.forwardRef)(SelectionFlow);
|
|
392
|
+
ForwardedSelectionFlow.displayName = "PisellSelectionFlow";
|
|
393
|
+
//#endregion
|
|
394
|
+
exports.default = ForwardedSelectionFlow;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CompiledSelectionFlowStep, SelectionFlowContextValue, SelectionFlowDraftAdapter, SelectionFlowModuleAdapter, SelectionFlowModuleRegistry, SelectionFlowStepConfig } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/components/PisellSelectionFlow/compiler.d.ts
|
|
4
|
+
type AnyAdapter = SelectionFlowModuleAdapter<any, any, string, string, any, any>;
|
|
5
|
+
type AnyRegistry = Record<string, AnyAdapter>;
|
|
6
|
+
declare const resolveFlowModuleAdapter: <TDraft, TDraftUpdate, TField extends string, TModuleType extends string, TServices, THostContext>(registry: SelectionFlowModuleRegistry<TDraft, TDraftUpdate, TField, TModuleType, TServices, THostContext>, type: string) => AnyAdapter;
|
|
7
|
+
declare const hasSelectionDraftFieldValue: <TDraft, TDraftUpdate, TField extends string>(draftAdapter: SelectionFlowDraftAdapter<TDraft, TDraftUpdate, TField>, draft: Readonly<TDraft>, field: TField) => boolean;
|
|
8
|
+
declare const compileSelectionFlowSteps: <TDraft, TDraftUpdate, TField extends string, TModuleType extends string, TServices, THostContext>(steps: readonly SelectionFlowStepConfig<TModuleType>[], context: SelectionFlowContextValue<TDraft, TDraftUpdate, TField, TModuleType, TServices, THostContext>, dependencySeedDraft: Readonly<TDraft>, registry: SelectionFlowModuleRegistry<TDraft, TDraftUpdate, TField, TModuleType, TServices, THostContext>, draftAdapter: SelectionFlowDraftAdapter<TDraft, TDraftUpdate, TField>) => readonly CompiledSelectionFlowStep<TModuleType>[];
|
|
9
|
+
declare const compileSelectionFlow: <TDraft, TDraftUpdate, TField extends string, TModuleType extends string, TServices, THostContext>(steps: readonly SelectionFlowStepConfig<TModuleType>[], context: SelectionFlowContextValue<TDraft, TDraftUpdate, TField, TModuleType, TServices, THostContext>, dependencySeedDraft: Readonly<TDraft>, registry: SelectionFlowModuleRegistry<TDraft, TDraftUpdate, TField, TModuleType, TServices, THostContext>, draftAdapter: SelectionFlowDraftAdapter<TDraft, TDraftUpdate, TField>) => readonly CompiledSelectionFlowStep<TModuleType>[];
|
|
10
|
+
declare const isSelectionModuleType: (registry: AnyRegistry, type: string) => boolean;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { compileSelectionFlow, compileSelectionFlowSteps, hasSelectionDraftFieldValue, isSelectionModuleType, resolveFlowModuleAdapter };
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
const require_objectSpread2 = require("../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
|
|
2
|
+
const require_types = require("./types.js");
|
|
3
|
+
//#region src/components/PisellSelectionFlow/compiler.ts
|
|
4
|
+
const resolveFlowModuleAdapter = (registry, type) => registry[type];
|
|
5
|
+
const hasSelectionDraftFieldValue = (draftAdapter, draft, field) => {
|
|
6
|
+
const value = draftAdapter.getFieldValue(draft, field);
|
|
7
|
+
if (value === null || typeof value === "undefined" || value === "") return false;
|
|
8
|
+
return !Array.isArray(value) || value.length > 0;
|
|
9
|
+
};
|
|
10
|
+
const normalizeModule = (input, stepKey, stepIndex, moduleIndex) => {
|
|
11
|
+
const config = typeof input === "string" ? { type: input } : input;
|
|
12
|
+
return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, config), {}, {
|
|
13
|
+
key: config.key || config.type,
|
|
14
|
+
stepKey,
|
|
15
|
+
stepIndex,
|
|
16
|
+
moduleIndex
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
const findCircularRequirements = (modules, registry, draftAdapter, initialDraft) => {
|
|
20
|
+
const providers = /* @__PURE__ */ new Map();
|
|
21
|
+
modules.forEach((module) => {
|
|
22
|
+
var _resolveFlowModuleAda;
|
|
23
|
+
(_resolveFlowModuleAda = resolveFlowModuleAdapter(registry, module.type)) === null || _resolveFlowModuleAda === void 0 || (_resolveFlowModuleAda = _resolveFlowModuleAda.provides) === null || _resolveFlowModuleAda === void 0 || _resolveFlowModuleAda.forEach((field) => {
|
|
24
|
+
providers.set(field, [...providers.get(field) || [], module]);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
const resolved = /* @__PURE__ */ new Set();
|
|
28
|
+
let progressed = true;
|
|
29
|
+
while (progressed) {
|
|
30
|
+
progressed = false;
|
|
31
|
+
for (const module of modules) {
|
|
32
|
+
if (resolved.has(module.key)) continue;
|
|
33
|
+
const adapter = resolveFlowModuleAdapter(registry, module.type);
|
|
34
|
+
if (!((adapter === null || adapter === void 0 ? void 0 : adapter.hardRequires) || []).every((field) => {
|
|
35
|
+
const candidates = (providers.get(field) || []).filter((provider) => provider.key !== module.key);
|
|
36
|
+
if (candidates.length === 0) return hasSelectionDraftFieldValue(draftAdapter, initialDraft, field);
|
|
37
|
+
return candidates.some((provider) => resolved.has(provider.key));
|
|
38
|
+
})) continue;
|
|
39
|
+
resolved.add(module.key);
|
|
40
|
+
progressed = true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const unresolved = modules.filter((module) => !resolved.has(module.key));
|
|
44
|
+
if (unresolved.length === 0) return null;
|
|
45
|
+
return unresolved.some((module) => {
|
|
46
|
+
var _resolveFlowModuleAda2;
|
|
47
|
+
return (((_resolveFlowModuleAda2 = resolveFlowModuleAdapter(registry, module.type)) === null || _resolveFlowModuleAda2 === void 0 ? void 0 : _resolveFlowModuleAda2.hardRequires) || []).some((field) => {
|
|
48
|
+
return (providers.get(field) || []).filter((provider) => provider.key !== module.key).length === 0 && !hasSelectionDraftFieldValue(draftAdapter, initialDraft, field);
|
|
49
|
+
});
|
|
50
|
+
}) ? null : unresolved.map((module) => module.type);
|
|
51
|
+
};
|
|
52
|
+
const compileSelectionFlowSteps = (steps, context, dependencySeedDraft, registry, draftAdapter) => {
|
|
53
|
+
const issues = [];
|
|
54
|
+
const stepKeys = /* @__PURE__ */ new Set();
|
|
55
|
+
const moduleKeys = /* @__PURE__ */ new Set();
|
|
56
|
+
const compiledSteps = [];
|
|
57
|
+
steps.forEach((step, sourceStepIndex) => {
|
|
58
|
+
const stepKey = String(step.key || "").trim();
|
|
59
|
+
if (!stepKey || stepKeys.has(stepKey)) issues.push({
|
|
60
|
+
code: "DUPLICATE_STEP_KEY",
|
|
61
|
+
message: stepKey ? `Selection flow contains duplicate step key "${stepKey}".` : "Selection flow step key cannot be empty.",
|
|
62
|
+
stepKey: stepKey || void 0
|
|
63
|
+
});
|
|
64
|
+
else stepKeys.add(stepKey);
|
|
65
|
+
if (!Array.isArray(step.modules) || step.modules.length === 0) {
|
|
66
|
+
issues.push({
|
|
67
|
+
code: "EMPTY_STEP",
|
|
68
|
+
message: `Selection flow step "${stepKey || sourceStepIndex}" has no modules.`,
|
|
69
|
+
stepKey: stepKey || void 0
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const applicableModules = [];
|
|
74
|
+
step.modules.forEach((input) => {
|
|
75
|
+
const module = normalizeModule(input, stepKey, compiledSteps.length, applicableModules.length);
|
|
76
|
+
const adapter = resolveFlowModuleAdapter(registry, module.type);
|
|
77
|
+
if (!adapter) {
|
|
78
|
+
issues.push({
|
|
79
|
+
code: "UNKNOWN_MODULE",
|
|
80
|
+
message: `Selection module type "${module.type}" is not registered.`,
|
|
81
|
+
stepKey,
|
|
82
|
+
moduleKey: module.key,
|
|
83
|
+
moduleType: module.type
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (moduleKeys.has(module.key)) {
|
|
88
|
+
issues.push({
|
|
89
|
+
code: "DUPLICATE_MODULE_KEY",
|
|
90
|
+
message: `Selection flow contains duplicate module key "${module.key}".`,
|
|
91
|
+
stepKey,
|
|
92
|
+
moduleKey: module.key,
|
|
93
|
+
moduleType: module.type
|
|
94
|
+
});
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
moduleKeys.add(module.key);
|
|
98
|
+
try {
|
|
99
|
+
if (adapter.isApplicable && !adapter.isApplicable(context, module)) return;
|
|
100
|
+
} catch (error) {
|
|
101
|
+
issues.push({
|
|
102
|
+
code: "APPLICABILITY_CHECK_FAILED",
|
|
103
|
+
message: `Selection module "${module.type}" applicability check failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
104
|
+
stepKey,
|
|
105
|
+
moduleKey: module.key,
|
|
106
|
+
moduleType: module.type
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
applicableModules.push(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, module), {}, { moduleIndex: applicableModules.length }));
|
|
111
|
+
});
|
|
112
|
+
if (applicableModules.length === 0) return;
|
|
113
|
+
const index = compiledSteps.length;
|
|
114
|
+
compiledSteps.push(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, step), {}, {
|
|
115
|
+
key: stepKey,
|
|
116
|
+
index,
|
|
117
|
+
modules: applicableModules.map((module) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, module), {}, { stepIndex: index }))
|
|
118
|
+
}));
|
|
119
|
+
});
|
|
120
|
+
const flatModules = compiledSteps.flatMap((step) => [...step.modules]);
|
|
121
|
+
if (flatModules.length === 0 && steps.length === 0) issues.push({
|
|
122
|
+
code: "EMPTY_FLOW",
|
|
123
|
+
message: "Selection flow has no applicable modules."
|
|
124
|
+
});
|
|
125
|
+
const circularPath = findCircularRequirements(flatModules, registry, draftAdapter, dependencySeedDraft);
|
|
126
|
+
if (circularPath) issues.push({
|
|
127
|
+
code: "CIRCULAR_HARD_REQUIREMENT",
|
|
128
|
+
message: `Selection flow contains unresolvable circular hard requirements among: ${circularPath.join(", ")}.`,
|
|
129
|
+
moduleType: circularPath[0]
|
|
130
|
+
});
|
|
131
|
+
const providers = /* @__PURE__ */ new Map();
|
|
132
|
+
flatModules.forEach((module, index) => {
|
|
133
|
+
var _resolveFlowModuleAda3;
|
|
134
|
+
(_resolveFlowModuleAda3 = resolveFlowModuleAdapter(registry, module.type)) === null || _resolveFlowModuleAda3 === void 0 || (_resolveFlowModuleAda3 = _resolveFlowModuleAda3.provides) === null || _resolveFlowModuleAda3 === void 0 || _resolveFlowModuleAda3.forEach((field) => {
|
|
135
|
+
providers.set(field, [...providers.get(field) || [], {
|
|
136
|
+
module,
|
|
137
|
+
index
|
|
138
|
+
}]);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
flatModules.forEach((module, index) => {
|
|
142
|
+
const adapter = resolveFlowModuleAdapter(registry, module.type);
|
|
143
|
+
for (const field of (adapter === null || adapter === void 0 ? void 0 : adapter.hardRequires) || []) {
|
|
144
|
+
const typedField = field;
|
|
145
|
+
const fieldProviders = (providers.get(typedField) || []).filter((provider) => provider.module.key !== module.key);
|
|
146
|
+
if (fieldProviders.length === 0) {
|
|
147
|
+
if (hasSelectionDraftFieldValue(draftAdapter, dependencySeedDraft, typedField)) continue;
|
|
148
|
+
issues.push({
|
|
149
|
+
code: "MISSING_HARD_REQUIREMENT",
|
|
150
|
+
message: `Selection module "${module.type}" requires Draft field "${typedField}", but no earlier module provides it.`,
|
|
151
|
+
stepKey: module.stepKey,
|
|
152
|
+
moduleKey: module.key,
|
|
153
|
+
moduleType: module.type,
|
|
154
|
+
requirementField: typedField
|
|
155
|
+
});
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (!fieldProviders.some((provider) => provider.index < index)) issues.push({
|
|
159
|
+
code: "INVALID_DEPENDENCY_ORDER",
|
|
160
|
+
message: `Selection module "${module.type}" requires Draft field "${typedField}" to be provided before it.`,
|
|
161
|
+
stepKey: module.stepKey,
|
|
162
|
+
moduleKey: module.key,
|
|
163
|
+
moduleType: module.type,
|
|
164
|
+
requirementField: typedField
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
if (issues.length > 0) throw new require_types.SelectionFlowCompileError(issues);
|
|
169
|
+
return compiledSteps;
|
|
170
|
+
};
|
|
171
|
+
const compileSelectionFlow = compileSelectionFlowSteps;
|
|
172
|
+
const isSelectionModuleType = (registry, type) => Boolean(registry[type]);
|
|
173
|
+
//#endregion
|
|
174
|
+
exports.compileSelectionFlow = compileSelectionFlow;
|
|
175
|
+
exports.compileSelectionFlowSteps = compileSelectionFlowSteps;
|
|
176
|
+
exports.hasSelectionDraftFieldValue = hasSelectionDraftFieldValue;
|
|
177
|
+
exports.isSelectionModuleType = isSelectionModuleType;
|
|
178
|
+
exports.resolveFlowModuleAdapter = resolveFlowModuleAdapter;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SelectionFlowContextValue } from "./types.js";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/PisellSelectionFlow/context.d.ts
|
|
5
|
+
type AnySelectionFlowContext = SelectionFlowContextValue<any, any, string, string, any, any>;
|
|
6
|
+
declare const useSelectionFlowContext: () => AnySelectionFlowContext;
|
|
7
|
+
declare const useTypedSelectionFlowContext: <TDraft, TDraftUpdate, TField extends string, TModuleType extends string, TServices = unknown, THostContext = unknown>() => SelectionFlowContextValue<TDraft, TDraftUpdate, TField, TModuleType, TServices, THostContext>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { useSelectionFlowContext, useTypedSelectionFlowContext };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const require_runtime = require("../../_virtual/_rolldown/runtime.js");
|
|
2
|
+
let react = require("react");
|
|
3
|
+
react = require_runtime.__toESM(react);
|
|
4
|
+
//#region src/components/PisellSelectionFlow/context.tsx
|
|
5
|
+
const SelectionFlowReactContext = (0, react.createContext)(null);
|
|
6
|
+
const SelectionFlowProvider = ({ value, children }) => /* @__PURE__ */ react.default.createElement(SelectionFlowReactContext.Provider, { value }, children);
|
|
7
|
+
const useSelectionFlowContext = () => {
|
|
8
|
+
const context = (0, react.useContext)(SelectionFlowReactContext);
|
|
9
|
+
if (!context) throw new Error("useSelectionFlowContext must be used inside PisellSelectionFlow");
|
|
10
|
+
return context;
|
|
11
|
+
};
|
|
12
|
+
const useTypedSelectionFlowContext = () => useSelectionFlowContext();
|
|
13
|
+
//#endregion
|
|
14
|
+
exports.SelectionFlowProvider = SelectionFlowProvider;
|
|
15
|
+
exports.useSelectionFlowContext = useSelectionFlowContext;
|
|
16
|
+
exports.useTypedSelectionFlowContext = useTypedSelectionFlowContext;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require("../../../_virtual/_rolldown/runtime.js");
|
|
2
|
+
const require_objectSpread2 = require("../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
//#region src/components/PisellSelectionFlow/hooks/useFlowDraft.ts
|
|
5
|
+
/** 统一管理不可变 Draft 与业务自定义合并策略。 */
|
|
6
|
+
const useFlowDraft = ({ initialDraft, draftAdapter, mountedRef, draftRevisionRef, onDraftChangeRef, processDraftChangeRef }) => {
|
|
7
|
+
const [draft, setDraft] = (0, react.useState)(() => initialDraft);
|
|
8
|
+
const draftRef = (0, react.useRef)(draft);
|
|
9
|
+
draftRef.current = draft;
|
|
10
|
+
return {
|
|
11
|
+
draft,
|
|
12
|
+
draftRef,
|
|
13
|
+
updateDraft: (0, react.useCallback)((update, meta) => {
|
|
14
|
+
var _onDraftChangeRef$cur;
|
|
15
|
+
if (!mountedRef.current) return;
|
|
16
|
+
const previousDraft = draftRef.current;
|
|
17
|
+
const nextDraft = draftAdapter.applyUpdate(previousDraft, update);
|
|
18
|
+
draftRevisionRef.current += 1;
|
|
19
|
+
draftRef.current = nextDraft;
|
|
20
|
+
setDraft(nextDraft);
|
|
21
|
+
(_onDraftChangeRef$cur = onDraftChangeRef.current) === null || _onDraftChangeRef$cur === void 0 || _onDraftChangeRef$cur.call(onDraftChangeRef, nextDraft);
|
|
22
|
+
processDraftChangeRef.current(require_objectSpread2._objectSpread2({
|
|
23
|
+
previousDraft,
|
|
24
|
+
draft: nextDraft
|
|
25
|
+
}, meta));
|
|
26
|
+
}, [
|
|
27
|
+
draftAdapter,
|
|
28
|
+
draftRevisionRef,
|
|
29
|
+
mountedRef,
|
|
30
|
+
onDraftChangeRef,
|
|
31
|
+
processDraftChangeRef
|
|
32
|
+
])
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
exports.useFlowDraft = useFlowDraft;
|