Skip to content

Commit 6b41090

Browse files
committed
address comment
1 parent 7912123 commit 6b41090

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

packages/core/src/shared/ui/nestedWizardPrompter.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,51 @@ import { Wizard, WizardOptions } from '../wizards/wizard'
77
import { WizardPrompter } from './wizardPrompter'
88
import { createHash } from 'crypto'
99

10+
/**
11+
* An abstract class that extends the base Wizard class plus the ability to
12+
* use other wizard classes as prompters
13+
*/
1014
export abstract class NestedWizard<T> extends Wizard<T> {
11-
// Map to store wizard instances
15+
/**
16+
* Map to store memoized wizard instances using SHA-256 hashed keys
17+
*/
1218
private wizardInstances: Map<string, any> = new Map()
1319

1420
protected constructor(options: WizardOptions<T>) {
1521
super(options)
1622
}
1723

18-
protected createWizardPrompter<T>(constructor: new (...args: any[]) => T, ...args: any[]): WizardPrompter<T> {
24+
/**
25+
* Creates or retrieves a memoized wizard prompter instance
26+
*
27+
* @param {new (...args: any[]) => T} constructor - The constructor function for creating the wizard instance
28+
* @param {...any[]} args - Arguments to pass to the constructor
29+
* @returns {WizardPrompter<T>} A wrapped wizard to be used as prompter in parent wizard class
30+
*
31+
* @remarks
32+
* This method uses memoization to cache wizard instances based on their constructor
33+
* name and arguments, allowing for restoring wizard state for back button.
34+
*
35+
* @example
36+
* this.createWizardPrompter(
37+
* TemplateParametersWizard,
38+
* template!.uri,
39+
* samSyncUrl,
40+
* syncMementoRootKey
41+
* ),
42+
*/
43+
protected createWizardPrompter<T extends Wizard<any>>(
44+
constructor: new (...args: any[]) => T,
45+
...args: ConstructorParameters<new (...args: any[]) => T>
46+
): WizardPrompter<T> {
1947
const memoizeKey = createHash('sha256')
2048
.update(constructor.name + JSON.stringify(args))
2149
.digest('hex')
22-
if (!this.wizardInstances.get(memoizeKey) as T) {
50+
51+
if (!this.wizardInstances.get(memoizeKey)) {
2352
this.wizardInstances.set(memoizeKey, new constructor(...args))
2453
}
54+
2555
return new WizardPrompter(this.wizardInstances.get(memoizeKey))
2656
}
2757
}

packages/core/src/shared/ui/wizardPrompter.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ import { Prompter, PromptResult } from './prompter'
1010
/**
1111
* Wraps {@link Wizard} object into its own {@link Prompter}, allowing wizards to use other
1212
* wizards in their flows.
13+
*
14+
* @remarks
15+
* - This class should not use direclty inside a parent class.
16+
* - Consider extending {@link NestedWizard} instead. Example: {@link SyncWizard}
1317
*/
1418

1519
// eslint-disable-next-line @typescript-eslint/naming-convention
1620
export const WIZARD_PROMPTER = 'WIZARD_PROMPTER'
21+
1722
export class WizardPrompter<T> extends Prompter<T> {
1823
public get recentItem(): any {
1924
return undefined

packages/core/src/shared/wizards/stateController.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export enum ControlSignal {
1616
* Value for indicating current direction of the wizard
1717
* Created mainly to support skipping prompters
1818
*/
19-
export enum DIRECTON {
19+
export enum DIRECTION {
2020
Forward,
2121
Backward,
2222
}
@@ -48,11 +48,11 @@ export class StateMachineController<TState> {
4848
private extraSteps = new Map<number, Branch<TState>>()
4949
private steps: Branch<TState> = []
5050
private internalStep: number = 0
51-
private direction: DIRECTON
51+
private direction: DIRECTION
5252

5353
public constructor(private state: TState = {} as TState) {
5454
this.previousStates = [_.cloneDeep(state)]
55-
this.direction = DIRECTON.Forward
55+
this.direction = DIRECTION.Forward
5656
}
5757

5858
public addStep(step: StepFunction<TState>): void {
@@ -82,14 +82,14 @@ export class StateMachineController<TState> {
8282

8383
this.state = this.previousStates.pop()!
8484
this.internalStep -= 1
85-
this.direction = DIRECTON.Backward
85+
this.direction = DIRECTION.Backward
8686
}
8787

8888
protected advanceState(nextState: TState): void {
8989
this.previousStates.push(this.state)
9090
this.state = nextState
9191
this.internalStep += 1
92-
this.direction = DIRECTON.Forward
92+
this.direction = DIRECTION.Forward
9393
}
9494

9595
protected detectCycle(step: StepFunction<TState>): TState | undefined {
@@ -122,7 +122,7 @@ export class StateMachineController<TState> {
122122
/**
123123
* Depending on current wizard direction, skip signal get converted to forward or backward control signal
124124
*/
125-
result.controlSignal = this.direction === DIRECTON.Forward ? undefined : ControlSignal.Back
125+
result.controlSignal = this.direction === DIRECTION.Forward ? undefined : ControlSignal.Back
126126
}
127127
return result
128128
} else {

0 commit comments

Comments
 (0)