@owlmeans/client-flow 0.1.2 → 0.1.4

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/README.md CHANGED
@@ -1,877 +1,68 @@
1
1
  # @owlmeans/client-flow
2
2
 
3
- Client-side configurable user flow management library for OwlMeans Common applications. This package provides a comprehensive system for implementing complex user workflows, authentication flows, and multi-step processes in React applications with state persistence and navigation integration.
3
+ Client-side flow orchestration service for managing multi-step workflows in browser environments.
4
4
 
5
5
  ## Overview
6
6
 
7
- The `@owlmeans/client-flow` package extends the base `@owlmeans/flow` package with client-specific functionality. It provides:
8
-
9
- - **Client Flow Management**: Complete client-side implementation of configurable user flows
10
- - **State Persistence**: Automatic flow state persistence across browser sessions
11
- - **Navigation Integration**: Seamless integration with React Router navigation
12
- - **Authentication Flows**: Pre-built authentication and authorization workflows
13
- - **Service Integration**: Integration with OwlMeans service and module systems
14
- - **React Components**: Flow-aware components and hooks for React applications
15
- - **Configuration Management**: Dynamic flow configuration from external sources
16
- - **Error Handling**: Robust error handling and recovery mechanisms
17
-
18
- This package is part of the OwlMeans flow management quadra:
19
- - **@owlmeans/flow**: Common flow interfaces and utilities
20
- - **@owlmeans/client-flow**: Client-side flow implementation *(this package)*
21
- - **@owlmeans/web-flow**: Web-specific flow components and utilities
22
- - **@owlmeans/server-flow**: Server-side flow processing
7
+ - `makeBasicFlowService(alias?)` creates a flow service for context registration
8
+ - `createFlowClient(context, nav)` — creates a `FlowClient` bound to the app context and navigator
9
+ - `FlowService` / `FlowClient` interfaces for flow state management and step transitions
10
+ - Used by `@owlmeans/web-flow` to drive navigation through workflow steps
23
11
 
24
12
  ## Installation
25
13
 
26
14
  ```bash
27
- npm install @owlmeans/client-flow react
15
+ bun add @owlmeans/client-flow
28
16
  ```
29
17
 
30
- ## Core Concepts
31
-
32
- ### Flow Models
33
- Flows are state machines that guide users through multi-step processes. Each flow consists of steps, transitions, and conditions that determine the user's path.
34
-
35
- ### Flow States
36
- Flow states represent the current position in a workflow and are automatically persisted to survive browser sessions and page reloads.
37
-
38
- ### Flow Service
39
- The central service that manages flow lifecycle, state transitions, and integration with other application services.
40
-
41
- ### Flow Client
42
- A client-side wrapper that provides an easy-to-use interface for flow operations with navigation integration.
43
-
44
- ## API Reference
18
+ ## Usage
45
19
 
46
- ### Factory Functions
47
-
48
- #### `makeBasicFlowService(alias?: string): FlowService`
49
-
50
- Creates a flow service instance for managing client-side flows.
20
+ Register the flow service in context setup:
51
21
 
52
22
  ```typescript
53
23
  import { makeBasicFlowService } from '@owlmeans/client-flow'
54
24
 
55
- const flowService = makeBasicFlowService('user-flows')
56
- ```
57
-
58
- **Parameters:**
59
- - `alias`: string (optional) - Service alias for registration, defaults to 'flow'
60
-
61
- **Returns:** FlowService instance ready for registration with context
62
-
63
- #### `createFlowClient<C, T>(context: T, nav: Navigator): FlowClient`
64
-
65
- Creates a flow client that integrates flows with navigation and context.
66
-
67
- ```typescript
68
- import { createFlowClient } from '@owlmeans/client-flow'
69
- import { useContext, useNavigate } from '@owlmeans/client'
70
-
71
- const context = useContext()
72
- const navigator = useNavigate()
73
- const flowClient = createFlowClient(context, navigator)
74
- ```
75
-
76
- **Parameters:**
77
- - `context`: T - Application context with flow service
78
- - `nav`: Navigator - Navigation service for routing integration
79
-
80
- **Returns:** FlowClient instance for flow operations
81
-
82
- ### Core Interfaces
83
-
84
- #### `FlowService`
85
-
86
- Main service interface for flow management and lifecycle operations.
87
-
88
- ```typescript
89
- interface FlowService extends LazyService {
90
- supplied: Promise<boolean> // Flow availability promise
91
- flow: FlowModel | null // Current active flow
92
-
93
- // Flow operations
94
- state(): Promise<FlowModel | null> // Get current flow state
95
- begin(slug?: string, from?: string): Promise<FlowModel> // Start new flow
96
- load(flow: string): Promise<FlowModel> // Load existing flow
97
- proceed(req?, dryRun?): Promise<string> // Proceed to next step
98
-
99
- // Configuration and providers
100
- config(): FlowConfig // Get flow configuration
101
- provideFlow: FlowProvider // Flow provider function
102
- resolvePair(): ResolvePair // Promise resolution pair
103
- }
104
- ```
105
-
106
- #### `FlowClient`
107
-
108
- Client-side flow wrapper with navigation and persistence integration.
109
-
110
- ```typescript
111
- interface FlowClient {
112
- boot(target?: string, from?: string): Promise<FlowClient> // Initialize flow client
113
- setup(flow: FlowModel): FlowClient // Setup with existing flow
114
- flow(): FlowModel // Get current flow model
115
- service(): ResolvedServiceRoute // Get target service route
116
- proceed(transition: FlowTransition, req?): Promise<void> // Execute transition
117
- persist(): Promise<boolean> // Persist current state
118
- }
119
- ```
120
-
121
- #### `StateRecord`
122
-
123
- Interface for flow state persistence records.
124
-
125
- ```typescript
126
- interface StateRecord extends ResourceRecord, FlowState {
127
- id: string // Record identifier
128
- flow: string // Flow type identifier
129
- step: string // Current step identifier
130
- service: string // Target service
131
- data: any // Flow-specific data
132
- // ... other FlowState properties
133
- }
134
- ```
135
-
136
- #### `StateResource`
137
-
138
- Resource interface for managing flow state persistence.
139
-
140
- ```typescript
141
- interface StateResource extends ClientResource<StateRecord> {
142
- // Inherits all standard resource methods for CRUD operations
143
- }
144
- ```
145
-
146
- ### Flow Service Methods Detailed Reference
147
-
148
- #### `state(): Promise<FlowModel | null>`
149
-
150
- **Purpose**: Retrieves the current active flow model
151
-
152
- **Behavior**:
153
- - Waits for flow service to be supplied/ready
154
- - Returns the currently active flow or null if no flow is active
155
- - Used to check flow status before operations
156
-
157
- **Usage**: Checking if a flow is currently active
158
-
159
- ```typescript
160
- const flowService = context.service<FlowService>('flow')
161
-
162
- const currentFlow = await flowService.state()
163
- if (currentFlow) {
164
- console.log('Active flow:', currentFlow.name)
165
- console.log('Current step:', currentFlow.step())
166
- } else {
167
- console.log('No active flow')
168
- }
25
+ context.registerService(makeBasicFlowService())
169
26
  ```
170
27
 
171
- #### `begin(slug?: string, from?: string): Promise<FlowModel>`
172
-
173
- **Purpose**: Starts a new flow with the specified configuration
174
-
175
- **Behavior**:
176
- - Creates a new flow model based on the slug
177
- - Sets the service as supplied/ready
178
- - Enters the flow from the specified step or initial step
179
- - Returns the active flow model
180
-
181
- **Usage**: Starting authentication, registration, or other workflows
182
-
183
- **Parameters**:
184
- - `slug`: string (optional) - Flow identifier, defaults to config.defaultFlow or STD_AUTH_FLOW
185
- - `from`: string (optional) - Starting step, defaults to flow's initial step
28
+ Create a flow client in a component or hook:
186
29
 
187
30
  ```typescript
188
- const flowService = context.service<FlowService>('flow')
31
+ import { createFlowClient, DEFAULT_ALIAS as FLOW_ALIAS } from '@owlmeans/client-flow'
32
+ import type { FlowService, FlowClient } from '@owlmeans/client-flow'
189
33
 
190
- // Start default authentication flow
191
- const authFlow = await flowService.begin()
192
-
193
- // Start specific flow from specific step
194
- const registrationFlow = await flowService.begin('user-registration', 'email-verification')
195
-
196
- // Start flow with default slug
197
- const defaultFlow = await flowService.begin('custom-onboarding')
198
- ```
199
-
200
- #### `load(flow: string): Promise<FlowModel>`
201
-
202
- **Purpose**: Loads and activates a flow from serialized state
203
-
204
- **Behavior**:
205
- - Recreates flow model from serialized state string
206
- - Sets the service as supplied/ready
207
- - Restores flow to its previous state
208
- - Returns the restored flow model
209
-
210
- **Usage**: Restoring flows from persistent storage
211
-
212
- ```typescript
213
- const flowService = context.service<FlowService>('flow')
34
+ const service = context.service<FlowService>(FLOW_ALIAS)
35
+ await service.ready()
214
36
 
215
- // Load flow from saved state
216
- const savedFlowState = localStorage.getItem('flow-state')
217
- if (savedFlowState) {
218
- const restoredFlow = await flowService.load(savedFlowState)
219
- console.log('Flow restored to step:', restoredFlow.step())
220
- }
37
+ const client = await createFlowClient(context, nav).boot(target)
38
+ // Navigate to next step
39
+ await client.proceed(transition, request)
221
40
  ```
222
41
 
223
- #### `proceed(req?: Partial<AbstractRequest>, dryRun?: boolean): Promise<string>`
42
+ ## API
224
43
 
225
- **Purpose**: Advances the flow to the next step based on conditions
44
+ ### `makeBasicFlowService(alias?): FlowService`
226
45
 
227
- **Behavior**:
228
- - Evaluates current step's transitions and conditions
229
- - Moves to the next appropriate step
230
- - Throws FlowUnsupported error (not implemented in basic service)
231
- - Should be overridden in specific implementations
46
+ Creates the flow service. `alias` defaults to `DEFAULT_ALIAS` (`'flow'`).
232
47
 
233
- **Usage**: Advancing through flow steps
234
-
235
- **Note**: The basic service throws `FlowUnsupported` - this should be implemented by specific flow implementations
236
-
237
- ```typescript
238
- // This would be implemented in a specific flow service
239
- const nextStep = await flowService.proceed({
240
- body: { userInput: 'some-data' }
241
- })
242
- ```
243
-
244
- #### `config(): FlowConfig`
245
-
246
- **Purpose**: Retrieves the current flow configuration
247
-
248
- **Behavior**:
249
- - Accesses flow configuration from context
250
- - Returns default empty config if not configured
251
- - Used for flow behavior customization
252
-
253
- **Usage**: Accessing flow settings and configuration
254
-
255
- ```typescript
256
- const flowService = context.service<FlowService>('flow')
257
-
258
- const config = flowService.config()
259
- console.log('Default flow:', config.defaultFlow)
260
- console.log('Available services:', config.services)
261
- ```
48
+ ### `createFlowClient(context, nav): FlowClient`
262
49
 
263
- ### Flow Client Methods Detailed Reference
264
-
265
- #### `boot(target?: string, from?: string): Promise<FlowClient>`
266
-
267
- **Purpose**: Initializes the flow client with optional target service and starting point
268
-
269
- **Behavior**:
270
- - Waits for flow service to be ready
271
- - Attempts to restore flow from persistent storage
272
- - Creates new flow if no saved state exists
273
- - Sets target service if provided
274
- - Returns the initialized client
275
-
276
- **Usage**: Starting the flow system in your application
277
-
278
- ```typescript
279
- const flowClient = createFlowClient(context, navigator)
280
-
281
- // Boot with specific target service
282
- await flowClient.boot('user-dashboard', 'login-step')
283
-
284
- // Boot with default behavior
285
- await flowClient.boot()
286
-
287
- // Boot without target, from saved state
288
- await flowClient.boot(null)
289
- ```
290
-
291
- #### `setup(flow: FlowModel): FlowClient`
292
-
293
- **Purpose**: Configures the client with an existing flow model
294
-
295
- **Behavior**:
296
- - Sets the provided flow as the active flow
297
- - Returns the client for method chaining
298
- - Used when you already have a flow model
299
-
300
- **Usage**: Using pre-configured flow models
301
-
302
- ```typescript
303
- const existingFlow = await flowService.begin('checkout-flow')
304
- const flowClient = createFlowClient(context, navigator)
305
- .setup(existingFlow)
306
- ```
307
-
308
- #### `flow(): FlowModel`
309
-
310
- **Purpose**: Returns the current active flow model
311
-
312
- **Behavior**: Direct access to the underlying flow model
313
-
314
- **Usage**: Accessing flow state and methods
315
-
316
- ```typescript
317
- const currentFlow = flowClient.flow()
318
- console.log('Current step:', currentFlow.step())
319
- console.log('Flow data:', currentFlow.data())
320
- ```
321
-
322
- #### `service(): ResolvedServiceRoute`
323
-
324
- **Purpose**: Returns the resolved service route for the target service
325
-
326
- **Behavior**:
327
- - Resolves the target service from the context
328
- - Returns route information for navigation
329
-
330
- **Usage**: Getting service routing information
331
-
332
- ```typescript
333
- const serviceRoute = flowClient.service()
334
- console.log('Target service:', serviceRoute.service)
335
- console.log('Service path:', serviceRoute.path)
336
- ```
337
-
338
- #### `proceed(transition: FlowTransition, req?: Partial<AbstractRequest>): Promise<void>`
339
-
340
- **Purpose**: Executes a flow transition with optional request data
341
-
342
- **Behavior**:
343
- - Executes the specified transition
344
- - Passes request data to the transition handler
345
- - Updates flow state based on transition result
346
- - Handles navigation if required
347
-
348
- **Usage**: Moving between flow steps
349
-
350
- ```typescript
351
- await flowClient.proceed('next', {
352
- body: { formData: userData }
353
- })
354
-
355
- await flowClient.proceed('back')
356
-
357
- await flowClient.proceed('submit', {
358
- params: { id: userId }
359
- })
360
- ```
361
-
362
- #### `persist(): Promise<boolean>`
363
-
364
- **Purpose**: Saves the current flow state to persistent storage
365
-
366
- **Behavior**:
367
- - Serializes current flow state
368
- - Saves to flow state resource
369
- - Returns success status
370
-
371
- **Usage**: Saving flow progress
372
-
373
- ```typescript
374
- const saved = await flowClient.persist()
375
- if (saved) {
376
- console.log('Flow state saved successfully')
377
- } else {
378
- console.log('Failed to save flow state')
379
- }
380
- ```
381
-
382
- ### Constants
383
-
384
- #### `DEFAULT_ALIAS`
385
- Default flow service alias (`'flow'`).
386
-
387
- #### `FLOW_STATE`
388
- Resource identifier for flow state persistence (`'state:flow'`).
389
-
390
- #### `REHACK_MOD`
391
- Internal module identifier for redirects (`'__redirect'`).
392
-
393
- ## Usage Examples
394
-
395
- ### Basic Flow Setup
396
-
397
- ```typescript
398
- import { makeBasicFlowService, createFlowClient } from '@owlmeans/client-flow'
399
- import { makeClientContext, useContext } from '@owlmeans/client'
400
-
401
- // Create context with flow service
402
- const context = makeClientContext(config)
403
- const flowService = makeBasicFlowService()
404
- context.registerService(flowService)
405
-
406
- // Initialize context
407
- await context.configure().init()
408
-
409
- // Create flow client
410
- function MyFlowComponent() {
411
- const context = useContext()
412
- const navigator = useNavigate()
413
-
414
- const [flowClient, setFlowClient] = useState(null)
415
-
416
- useEffect(() => {
417
- const initFlow = async () => {
418
- const client = createFlowClient(context, navigator)
419
- await client.boot('user-onboarding')
420
- setFlowClient(client)
421
- }
422
-
423
- initFlow()
424
- }, [])
425
-
426
- return flowClient ? <FlowRenderer client={flowClient} /> : <div>Loading...</div>
427
- }
428
- ```
429
-
430
- ### Authentication Flow Implementation
431
-
432
- ```typescript
433
- import { makeBasicFlowService } from '@owlmeans/client-flow'
434
- import { STD_AUTH_FLOW } from '@owlmeans/flow'
435
-
436
- // Setup authentication flow
437
- const context = makeClientContext({
438
- service: 'my-app',
439
- // ... other config
440
- flowConfig: {
441
- defaultFlow: STD_AUTH_FLOW,
442
- services: {
443
- auth: 'authentication-service',
444
- dashboard: 'user-dashboard'
445
- },
446
- modules: {
447
- login: 'auth-login-module',
448
- register: 'auth-register-module'
449
- }
450
- }
451
- })
452
-
453
- const flowService = makeBasicFlowService('auth-flow')
454
- context.registerService(flowService)
455
-
456
- // Use in component
457
- function AuthFlow() {
458
- const context = useContext()
459
- const navigator = useNavigate()
460
- const [currentStep, setCurrentStep] = useState(null)
461
-
462
- useEffect(() => {
463
- const startAuthFlow = async () => {
464
- const client = createFlowClient(context, navigator)
465
- await client.boot('dashboard', 'login')
466
-
467
- const flow = client.flow()
468
- setCurrentStep(flow.step())
469
- }
470
-
471
- startAuthFlow()
472
- }, [])
473
-
474
- const handleLogin = async (credentials) => {
475
- const client = createFlowClient(context, navigator)
476
- await client.proceed('authenticate', {
477
- body: credentials
478
- })
479
-
480
- // Persist progress
481
- await client.persist()
482
-
483
- // Update current step
484
- setCurrentStep(client.flow().step())
485
- }
486
-
487
- return (
488
- <div>
489
- <h2>Authentication Flow</h2>
490
- <p>Current Step: {currentStep}</p>
491
- {currentStep === 'login' && <LoginForm onSubmit={handleLogin} />}
492
- {currentStep === 'verified' && <Navigate to="/dashboard" />}
493
- </div>
494
- )
495
- }
496
- ```
497
-
498
- ### Multi-Step Registration Flow
499
-
500
- ```typescript
501
- interface RegistrationData {
502
- personalInfo: { name: string; email: string }
503
- preferences: { theme: string; notifications: boolean }
504
- verification: { code: string }
505
- }
506
-
507
- function RegistrationFlow() {
508
- const context = useContext()
509
- const navigator = useNavigate()
510
- const [flowClient, setFlowClient] = useState<FlowClient | null>(null)
511
- const [registrationData, setRegistrationData] = useState<Partial<RegistrationData>>({})
512
-
513
- useEffect(() => {
514
- const initRegistration = async () => {
515
- const client = createFlowClient(context, navigator)
516
- await client.boot('user-registration', 'personal-info')
517
- setFlowClient(client)
518
- }
519
-
520
- initRegistration()
521
- }, [])
522
-
523
- const proceedToNext = async (stepData: any) => {
524
- if (!flowClient) return
525
-
526
- // Update registration data
527
- const updatedData = { ...registrationData, ...stepData }
528
- setRegistrationData(updatedData)
529
-
530
- // Proceed to next step
531
- await flowClient.proceed('next', {
532
- body: updatedData
533
- })
534
-
535
- // Persist state
536
- await flowClient.persist()
537
- }
538
-
539
- const getCurrentStep = () => {
540
- return flowClient?.flow().step() || 'loading'
541
- }
542
-
543
- const renderCurrentStep = () => {
544
- const step = getCurrentStep()
545
-
546
- switch (step) {
547
- case 'personal-info':
548
- return <PersonalInfoForm onSubmit={proceedToNext} />
549
- case 'preferences':
550
- return <PreferencesForm onSubmit={proceedToNext} />
551
- case 'verification':
552
- return <VerificationForm onSubmit={proceedToNext} />
553
- case 'complete':
554
- return <RegistrationComplete />
555
- default:
556
- return <div>Loading...</div>
557
- }
558
- }
559
-
560
- return (
561
- <div>
562
- <h2>Registration Flow</h2>
563
- <div>Step: {getCurrentStep()}</div>
564
- {renderCurrentStep()}
565
- </div>
566
- )
567
- }
568
- ```
569
-
570
- ### Flow State Persistence
571
-
572
- ```typescript
573
- import { appendClientResource } from '@owlmeans/client-resource'
574
- import { FLOW_STATE } from '@owlmeans/client-flow'
575
-
576
- // Setup flow state resource
577
- appendClientResource(context, FLOW_STATE)
578
-
579
- class FlowStateManager {
580
- constructor(private context: ClientContext) {}
581
-
582
- async saveFlowState(flowClient: FlowClient): Promise<boolean> {
583
- try {
584
- const flow = flowClient.flow()
585
- const stateResource = this.context.resource<StateResource>(FLOW_STATE)
586
-
587
- await stateResource.save({
588
- id: FLOW_STATE,
589
- flow: flow.name,
590
- step: flow.step(),
591
- service: flowClient.service().service,
592
- data: flow.data(),
593
- timestamp: new Date()
594
- })
595
-
596
- return true
597
- } catch (error) {
598
- console.error('Failed to save flow state:', error)
599
- return false
600
- }
601
- }
602
-
603
- async loadFlowState(): Promise<StateRecord | null> {
604
- try {
605
- const stateResource = this.context.resource<StateResource>(FLOW_STATE)
606
- return await stateResource.load(FLOW_STATE)
607
- } catch (error) {
608
- console.error('Failed to load flow state:', error)
609
- return null
610
- }
611
- }
612
-
613
- async clearFlowState(): Promise<void> {
614
- try {
615
- const stateResource = this.context.resource<StateResource>(FLOW_STATE)
616
- await stateResource.delete(FLOW_STATE)
617
- } catch (error) {
618
- console.error('Failed to clear flow state:', error)
619
- }
620
- }
621
- }
622
-
623
- // Usage
624
- const stateManager = new FlowStateManager(context)
625
-
626
- // Auto-save flow state
627
- const flowClient = createFlowClient(context, navigator)
628
- await flowClient.boot()
629
-
630
- // Save state after each step
631
- await stateManager.saveFlowState(flowClient)
632
-
633
- // Restore on application start
634
- const savedState = await stateManager.loadFlowState()
635
- if (savedState) {
636
- const flowService = context.service<FlowService>('flow')
637
- const restoredFlow = await flowService.begin(savedState.flow)
638
- restoredFlow.setState(savedState)
639
- }
640
- ```
641
-
642
- ### Custom Flow Service
643
-
644
- ```typescript
645
- import { makeBasicFlowService } from '@owlmeans/client-flow'
646
-
647
- class CustomFlowService extends makeBasicFlowService('custom') {
648
- async proceed(req?: Partial<AbstractRequest>, dryRun?: boolean): Promise<string> {
649
- if (!this.flow) {
650
- throw new Error('No active flow')
651
- }
652
-
653
- const currentStep = this.flow.step()
654
- const transitions = this.flow.transitions()
655
-
656
- // Custom logic for determining next step
657
- let nextStep = 'default'
658
-
659
- if (req?.body?.action === 'skip') {
660
- nextStep = this.findSkipTransition(transitions)
661
- } else if (req?.body?.action === 'back') {
662
- nextStep = this.findBackTransition(transitions)
663
- } else {
664
- nextStep = this.findNextTransition(transitions, req)
665
- }
666
-
667
- if (!dryRun) {
668
- await this.flow.transition(nextStep, req)
669
- }
670
-
671
- return nextStep
672
- }
673
-
674
- private findNextTransition(transitions: any[], req?: any): string {
675
- // Implement custom transition logic
676
- return transitions[0]?.target || 'end'
677
- }
678
-
679
- private findSkipTransition(transitions: any[]): string {
680
- return transitions.find(t => t.type === 'skip')?.target || 'end'
681
- }
682
-
683
- private findBackTransition(transitions: any[]): string {
684
- return transitions.find(t => t.type === 'back')?.target || 'start'
685
- }
686
- }
687
-
688
- // Register custom service
689
- const customFlowService = new CustomFlowService()
690
- context.registerService(customFlowService)
691
- ```
692
-
693
- ### Flow-Aware React Hook
694
-
695
- ```typescript
696
- import { useState, useEffect } from 'react'
697
- import { useContext } from '@owlmeans/client'
698
-
699
- interface UseFlowResult {
700
- flowClient: FlowClient | null
701
- currentStep: string | null
702
- isLoading: boolean
703
- proceed: (action: string, data?: any) => Promise<void>
704
- persist: () => Promise<boolean>
705
- }
706
-
707
- export function useFlow(flowType?: string, targetService?: string): UseFlowResult {
708
- const context = useContext()
709
- const navigator = useNavigate()
710
- const [flowClient, setFlowClient] = useState<FlowClient | null>(null)
711
- const [currentStep, setCurrentStep] = useState<string | null>(null)
712
- const [isLoading, setIsLoading] = useState(true)
713
-
714
- useEffect(() => {
715
- const initFlow = async () => {
716
- try {
717
- const client = createFlowClient(context, navigator)
718
- await client.boot(targetService)
719
-
720
- if (flowType) {
721
- const flowService = context.service<FlowService>('flow')
722
- const flow = await flowService.begin(flowType)
723
- client.setup(flow)
724
- }
725
-
726
- setFlowClient(client)
727
- setCurrentStep(client.flow().step())
728
- } catch (error) {
729
- console.error('Flow initialization failed:', error)
730
- } finally {
731
- setIsLoading(false)
732
- }
733
- }
734
-
735
- initFlow()
736
- }, [flowType, targetService])
737
-
738
- const proceed = async (action: string, data?: any) => {
739
- if (!flowClient) return
740
-
741
- await flowClient.proceed(action, { body: data })
742
- setCurrentStep(flowClient.flow().step())
743
- }
744
-
745
- const persist = async (): Promise<boolean> => {
746
- if (!flowClient) return false
747
- return await flowClient.persist()
748
- }
749
-
750
- return {
751
- flowClient,
752
- currentStep,
753
- isLoading,
754
- proceed,
755
- persist
756
- }
757
- }
758
-
759
- // Usage in component
760
- function FlowBasedComponent() {
761
- const { currentStep, isLoading, proceed, persist } = useFlow('onboarding', 'dashboard')
762
-
763
- if (isLoading) {
764
- return <div>Initializing flow...</div>
765
- }
766
-
767
- const handleNext = async (data: any) => {
768
- await proceed('next', data)
769
- await persist()
770
- }
771
-
772
- return (
773
- <div>
774
- <h3>Current Step: {currentStep}</h3>
775
- {currentStep === 'welcome' && <WelcomeStep onNext={handleNext} />}
776
- {currentStep === 'setup' && <SetupStep onNext={handleNext} />}
777
- {currentStep === 'complete' && <CompleteStep />}
778
- </div>
779
- )
780
- }
781
- ```
782
-
783
- ## Error Handling
784
-
785
- The package integrates with the OwlMeans error system and may throw the following errors:
786
-
787
- ### `FlowUnsupported`
788
- Thrown when an unsupported flow operation is attempted.
789
-
790
- ### `UnknownFlow`
791
- Thrown when trying to access a flow that hasn't been registered.
792
-
793
- ### `FlowTargetError`
794
- Thrown when the target service for a flow cannot be resolved.
795
-
796
- ### `FlowStepMissconfigured`
797
- Thrown when flow steps are not properly configured.
798
-
799
- ```typescript
800
- import { FlowUnsupported, UnknownFlow, FlowTargetError } from '@owlmeans/flow'
801
-
802
- const handleFlowError = async () => {
803
- try {
804
- await flowClient.proceed('invalid-transition')
805
- } catch (error) {
806
- if (error instanceof FlowUnsupported) {
807
- console.error('Flow operation not supported')
808
- } else if (error instanceof UnknownFlow) {
809
- console.error('Flow not found:', error.message)
810
- } else if (error instanceof FlowTargetError) {
811
- console.error('Invalid flow target:', error.message)
812
- }
813
- }
814
- }
815
- ```
816
-
817
- ## Integration with Other Packages
818
-
819
- ### Authentication Integration
820
- ```typescript
821
- import { makeAuthService } from '@owlmeans/client-auth'
822
- import { makeBasicFlowService } from '@owlmeans/client-flow'
823
-
824
- // Setup authentication flow
825
- const context = makeClientContext(config)
826
- const authService = makeAuthService()
827
- const flowService = makeBasicFlowService()
828
-
829
- context.registerService(authService)
830
- context.registerService(flowService)
831
- ```
832
-
833
- ### Resource Integration
834
- ```typescript
835
- import { appendClientResource } from '@owlmeans/client-resource'
836
- import { FLOW_STATE } from '@owlmeans/client-flow'
837
-
838
- // Setup flow state persistence
839
- appendClientResource(context, FLOW_STATE)
840
- ```
841
-
842
- ### Navigation Integration
843
- ```typescript
844
- import { useNavigate } from '@owlmeans/client'
845
- import { createFlowClient } from '@owlmeans/client-flow'
846
-
847
- const navigator = useNavigate()
848
- const flowClient = createFlowClient(context, navigator)
849
- ```
50
+ Creates a flow client with methods:
51
+ - `boot(target, from?)` — load and initialize flow for a target slug
52
+ - `setup(flow)` set the current flow model
53
+ - `proceed(transition, req?)` — advance to the next step
54
+ - `persist()` save flow state
850
55
 
851
- ## Best Practices
56
+ ### `DEFAULT_ALIAS`
852
57
 
853
- 1. **State Persistence**: Always persist flow state for long-running processes
854
- 2. **Error Handling**: Implement comprehensive error handling for flow operations
855
- 3. **Flow Design**: Design flows with clear steps and transition conditions
856
- 4. **Service Integration**: Properly configure target services for flows
857
- 5. **React Integration**: Use hooks for clean React component integration
858
- 6. **Testing**: Test flow transitions and error conditions thoroughly
859
- 7. **Configuration**: Use external configuration for flexible flow behavior
58
+ `'flow'` the default service alias.
860
59
 
861
- ## Dependencies
60
+ ### `FLOW_STATE`
862
61
 
863
- This package depends on:
864
- - `@owlmeans/flow` - Core flow interfaces and utilities
865
- - `@owlmeans/client-context` - Client context management
866
- - `@owlmeans/client-module` - Client module system
867
- - `@owlmeans/client-resource` - Client resource management
868
- - `@owlmeans/context` - Core context system
869
- - `react` - React library (peer dependency)
62
+ `'state:flow'` key used to store flow state in the client resource layer.
870
63
 
871
64
  ## Related Packages
872
65
 
873
- - [`@owlmeans/flow`](../flow) - Core flow system
874
- - [`@owlmeans/web-flow`](../web-flow) - Web-specific flow components
875
- - [`@owlmeans/server-flow`](../server-flow) - Server-side flow processing
876
- - [`@owlmeans/client-auth`](../client-auth) - Authentication with flow integration
877
- - [`@owlmeans/client`](../client) - Base React client library
66
+ - [`@owlmeans/flow`](../flow) `FlowModel`, `FlowConfig`, `FlowTransition` types
67
+ - [`@owlmeans/web-flow`](../web-flow) React hook (`useFlow`) built on top of `createFlowClient`
68
+ - [`@owlmeans/client-resource`](../client-resource) used internally to persist flow state
package/build/client.js CHANGED
@@ -1,4 +1,4 @@
1
- import { module, stab } from '@owlmeans/client-module';
1
+ import { entrypoint, stab } from '@owlmeans/client-entrypoint';
2
2
  import { route, frontend } from '@owlmeans/route';
3
3
  import { FlowStepMissconfigured, FlowTargetError, TARGET_SERVICE } from '@owlmeans/flow';
4
4
  import { ResilientError } from '@owlmeans/error';
@@ -67,13 +67,13 @@ export const createFlowClient = (context, nav) => {
67
67
  let redirectTo;
68
68
  // @TODO Properly use target service - as a way to build the redirect URL
69
69
  if (step.service === TARGET_SERVICE) {
70
- context.registerModule(module(route(REHACK_MOD, DISPATCHER_PATH, frontend({ service: model.state().service })), stab));
71
- redirectTo = context.module(REHACK_MOD);
70
+ context.registerEntrypoint(entrypoint(route(REHACK_MOD, DISPATCHER_PATH, frontend({ service: model.state().service })), stab));
71
+ redirectTo = context.entrypoint(REHACK_MOD);
72
72
  await redirectTo.resolve();
73
73
  step.module = REHACK_MOD;
74
74
  }
75
75
  else {
76
- redirectTo = context.module(step.module);
76
+ redirectTo = context.entrypoint(step.module);
77
77
  }
78
78
  const [url] = await redirectTo.call(req);
79
79
  if (url.startsWith('http')) {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/build/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { LazyService } from '@owlmeans/context';
2
2
  import type { FlowConfig, FlowModel, FlowProvider, FlowState, FlowTransition } from '@owlmeans/flow';
3
- import type { AbstractRequest } from '@owlmeans/module';
3
+ import type { AbstractRequest } from '@owlmeans/entrypoint';
4
4
  import type { ResourceRecord } from '@owlmeans/resource';
5
5
  import type { ResolvedServiceRoute } from '@owlmeans/route';
6
6
  import type { ClientResource } from '@owlmeans/client-resource';
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAE/D,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAE1B,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IAEtB,KAAK,EAAE,MAAM,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;IAEtC,WAAW,EAAE,MAAM,WAAW,CAAA;IAE9B,MAAM,EAAE,MAAM,UAAU,CAAA;IAExB,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IAE3D,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IAE1C,WAAW,EAAE,YAAY,CAAA;IAEzB,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAC/E;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAA;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;IACnE,KAAK,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,UAAU,CAAA;IACtC,IAAI,EAAE,MAAM,SAAS,CAAA;IACrB,OAAO,EAAE,MAAM,oBAAoB,CAAA;IACnC,OAAO,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvF,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc,EAAE,SAAS;CAAG;AAEjE,MAAM,WAAW,aAAc,SAAQ,cAAc,CAAC,WAAW,CAAC;CAAG"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAE/D,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAE1B,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IAEtB,KAAK,EAAE,MAAM,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;IAEtC,WAAW,EAAE,MAAM,WAAW,CAAA;IAE9B,MAAM,EAAE,MAAM,UAAU,CAAA;IAExB,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IAE3D,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IAE1C,WAAW,EAAE,YAAY,CAAA;IAEzB,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAC/E;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAA;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;IACnE,KAAK,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,UAAU,CAAA;IACtC,IAAI,EAAE,MAAM,SAAS,CAAA;IACrB,OAAO,EAAE,MAAM,oBAAoB,CAAA;IACnC,OAAO,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvF,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc,EAAE,SAAS;CAAG;AAEjE,MAAM,WAAW,aAAc,SAAQ,cAAc,CAAC,WAAW,CAAC;CAAG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/client-flow",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -21,26 +21,27 @@
21
21
  }
22
22
  },
23
23
  "dependencies": {
24
- "@owlmeans/auth-common": "^0.1.2",
25
- "@owlmeans/client": "^0.1.2",
26
- "@owlmeans/client-context": "^0.1.2",
27
- "@owlmeans/client-module": "^0.1.2",
28
- "@owlmeans/client-resource": "^0.1.2",
29
- "@owlmeans/config": "^0.1.2",
30
- "@owlmeans/context": "^0.1.2",
31
- "@owlmeans/error": "^0.1.2",
32
- "@owlmeans/flow": "^0.1.2",
33
- "@owlmeans/module": "^0.1.2",
34
- "@owlmeans/resource": "^0.1.2",
35
- "@owlmeans/route": "^0.1.2"
24
+ "@owlmeans/auth-common": "^0.1.4",
25
+ "@owlmeans/client": "^0.1.4",
26
+ "@owlmeans/client-context": "^0.1.4",
27
+ "@owlmeans/client-entrypoint": "^0.1.4",
28
+ "@owlmeans/client-resource": "^0.1.4",
29
+ "@owlmeans/config": "^0.1.4",
30
+ "@owlmeans/context": "^0.1.4",
31
+ "@owlmeans/error": "^0.1.4",
32
+ "@owlmeans/flow": "^0.1.4",
33
+ "@owlmeans/entrypoint": "^0.1.4",
34
+ "@owlmeans/resource": "^0.1.4",
35
+ "@owlmeans/route": "^0.1.4"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": "*"
39
39
  },
40
40
  "devDependencies": {
41
+ "@owlmeans/dep-config": "workspace:*",
41
42
  "nodemon": "^3.1.11",
42
43
  "npm-check": "^6.0.1",
43
- "typescript": "^5.8.3"
44
+ "typescript": "^6.0.2"
44
45
  },
45
46
  "publishConfig": {
46
47
  "access": "public"
package/src/client.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { ClientContext, Navigator } from '@owlmeans/client'
2
2
  import type { ClientConfig } from '@owlmeans/client-context'
3
- import type { ClientModule } from '@owlmeans/client-module'
4
- import { module, stab } from '@owlmeans/client-module'
3
+ import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
4
+ import { entrypoint, stab } from '@owlmeans/client-entrypoint'
5
5
  import type { ResolvedServiceRoute } from '@owlmeans/route'
6
6
  import { route, frontend } from '@owlmeans/route'
7
7
  import { FlowStepMissconfigured, FlowTargetError, TARGET_SERVICE } from '@owlmeans/flow'
@@ -87,17 +87,17 @@ export const createFlowClient = <C extends ClientConfig, T extends ClientContext
87
87
  { ...previous, ...req?.params, ...req?.query } as Record<string, string>
88
88
  )
89
89
 
90
- let redirectTo: ClientModule<string>
90
+ let redirectTo: ClientEntrypoint<string>
91
91
  // @TODO Properly use target service - as a way to build the redirect URL
92
92
  if (step.service === TARGET_SERVICE) {
93
- context.registerModule(module(
93
+ context.registerEntrypoint(entrypoint(
94
94
  route(REHACK_MOD, DISPATCHER_PATH, frontend({ service: model.state().service })), stab
95
95
  ))
96
- redirectTo = context.module<ClientModule<string>>(REHACK_MOD)
96
+ redirectTo = context.entrypoint<ClientEntrypoint<string>>(REHACK_MOD)
97
97
  await redirectTo.resolve()
98
98
  step.module = REHACK_MOD
99
99
  } else {
100
- redirectTo = context.module<ClientModule>(step.module)
100
+ redirectTo = context.entrypoint<ClientEntrypoint>(step.module)
101
101
  }
102
102
 
103
103
  const [url] = await redirectTo.call<string>(req)
package/src/types.ts CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  import type { LazyService } from '@owlmeans/context'
3
3
  import type { FlowConfig, FlowModel, FlowProvider, FlowState, FlowTransition } from '@owlmeans/flow'
4
- import type { AbstractRequest } from '@owlmeans/module'
4
+ import type { AbstractRequest } from '@owlmeans/entrypoint'
5
5
  import type { ResourceRecord } from '@owlmeans/resource'
6
6
  import type { ResolvedServiceRoute } from '@owlmeans/route'
7
7
  import type { ClientResource } from '@owlmeans/client-resource'
package/tsconfig.json CHANGED
@@ -1,15 +1,10 @@
1
1
  {
2
2
  "extends": [
3
- "../tsconfig.default.json"
3
+ "@owlmeans/dep-config/tsconfig.base.json"
4
4
  ],
5
5
  "compilerOptions": {
6
- "rootDir": "./src/", /* Specify the root folder within your source files. */
7
- "outDir": "./build/", /* Specify an output folder for all emitted files. */
8
- "moduleResolution": "Bundler"
6
+ "rootDir": "./src/",
7
+ "outDir": "./build/"
9
8
  },
10
- "exclude": [
11
- "./dist/**/*",
12
- "./build/**/*",
13
- "./*.ts"
14
- ]
15
- }
9
+ "exclude": ["./dist/**/*", "./build/**/*", "./*.ts"]
10
+ }
package/build/helper.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import type { ClientContext } from "@owlmeans/client";
2
- import type { ClientConfig } from "@owlmeans/client-context";
3
- import type { StateResource } from "./types.js";
4
- export declare const getFlowResource: <C extends ClientConfig = ClientConfig, T extends ClientContext<C> = ClientContext<C>>(context: T) => StateResource;
5
- //# sourceMappingURL=helper.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,eAAO,MAAM,eAAe,GAC1B,CAAC,SAAS,YAAY,GAAG,YAAY,EACrC,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,EAC7C,SAAS,CAAC,KAAG,aAA6C,CAAA"}
package/build/helper.js DELETED
@@ -1,3 +0,0 @@
1
- import { FLOW_STATE } from "./consts.js";
2
- export const getFlowResource = (context) => context.resource(FLOW_STATE);
3
- //# sourceMappingURL=helper.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAGxC,MAAM,CAAC,MAAM,eAAe,GAAG,CAG7B,OAAU,EAAiB,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA"}