@owlmeans/client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +688 -0
  3. package/build/app.d.ts +4 -0
  4. package/build/app.d.ts.map +1 -0
  5. package/build/app.js +10 -0
  6. package/build/app.js.map +1 -0
  7. package/build/components/index.d.ts +4 -0
  8. package/build/components/index.d.ts.map +1 -0
  9. package/build/components/index.js +3 -0
  10. package/build/components/index.js.map +1 -0
  11. package/build/components/modal.d.ts +7 -0
  12. package/build/components/modal.d.ts.map +1 -0
  13. package/build/components/modal.js +66 -0
  14. package/build/components/modal.js.map +1 -0
  15. package/build/components/toggle.d.ts +3 -0
  16. package/build/components/toggle.d.ts.map +1 -0
  17. package/build/components/toggle.js +20 -0
  18. package/build/components/toggle.js.map +1 -0
  19. package/build/components/types.d.ts +50 -0
  20. package/build/components/types.d.ts.map +1 -0
  21. package/build/components/types.js +2 -0
  22. package/build/components/types.js.map +1 -0
  23. package/build/consts.d.ts +5 -0
  24. package/build/consts.d.ts.map +1 -0
  25. package/build/consts.js +5 -0
  26. package/build/consts.js.map +1 -0
  27. package/build/context.d.ts +8 -0
  28. package/build/context.d.ts.map +1 -0
  29. package/build/context.js +47 -0
  30. package/build/context.js.map +1 -0
  31. package/build/debug.d.ts +4 -0
  32. package/build/debug.d.ts.map +1 -0
  33. package/build/debug.js +12 -0
  34. package/build/debug.js.map +1 -0
  35. package/build/errors.d.ts +18 -0
  36. package/build/errors.d.ts.map +1 -0
  37. package/build/errors.js +34 -0
  38. package/build/errors.js.map +1 -0
  39. package/build/helper.d.ts +4 -0
  40. package/build/helper.d.ts.map +1 -0
  41. package/build/helper.js +30 -0
  42. package/build/helper.js.map +1 -0
  43. package/build/index.d.ts +15 -0
  44. package/build/index.d.ts.map +1 -0
  45. package/build/index.js +15 -0
  46. package/build/index.js.map +1 -0
  47. package/build/module.d.ts +3 -0
  48. package/build/module.d.ts.map +1 -0
  49. package/build/module.js +4 -0
  50. package/build/module.js.map +1 -0
  51. package/build/navigate.d.ts +3 -0
  52. package/build/navigate.d.ts.map +1 -0
  53. package/build/navigate.js +39 -0
  54. package/build/navigate.js.map +1 -0
  55. package/build/router.d.ts +5 -0
  56. package/build/router.d.ts.map +1 -0
  57. package/build/router.js +53 -0
  58. package/build/router.js.map +1 -0
  59. package/build/services/debug.d.ts +6 -0
  60. package/build/services/debug.d.ts.map +1 -0
  61. package/build/services/debug.js +83 -0
  62. package/build/services/debug.js.map +1 -0
  63. package/build/services/index.d.ts +2 -0
  64. package/build/services/index.d.ts.map +1 -0
  65. package/build/services/index.js +2 -0
  66. package/build/services/index.js.map +1 -0
  67. package/build/store.d.ts +4 -0
  68. package/build/store.d.ts.map +1 -0
  69. package/build/store.js +49 -0
  70. package/build/store.js.map +1 -0
  71. package/build/types.d.ts +57 -0
  72. package/build/types.d.ts.map +1 -0
  73. package/build/types.js +2 -0
  74. package/build/types.js.map +1 -0
  75. package/build/utils/index.d.ts +4 -0
  76. package/build/utils/index.d.ts.map +1 -0
  77. package/build/utils/index.js +4 -0
  78. package/build/utils/index.js.map +1 -0
  79. package/build/utils/module.d.ts +3 -0
  80. package/build/utils/module.d.ts.map +1 -0
  81. package/build/utils/module.js +8 -0
  82. package/build/utils/module.js.map +1 -0
  83. package/build/utils/route.d.ts +16 -0
  84. package/build/utils/route.d.ts.map +1 -0
  85. package/build/utils/route.js +65 -0
  86. package/build/utils/route.js.map +1 -0
  87. package/build/utils/router.d.ts +16 -0
  88. package/build/utils/router.d.ts.map +1 -0
  89. package/build/utils/router.js +36 -0
  90. package/build/utils/router.js.map +1 -0
  91. package/build/value.d.ts +4 -0
  92. package/build/value.d.ts.map +1 -0
  93. package/build/value.js +48 -0
  94. package/build/value.js.map +1 -0
  95. package/package.json +66 -0
  96. package/src/app.tsx +17 -0
  97. package/src/components/index.ts +4 -0
  98. package/src/components/modal.ts +89 -0
  99. package/src/components/toggle.ts +22 -0
  100. package/src/components/types.ts +57 -0
  101. package/src/consts.ts +7 -0
  102. package/src/context.ts +61 -0
  103. package/src/debug.ts +14 -0
  104. package/src/errors.ts +44 -0
  105. package/src/helper.tsx +51 -0
  106. package/src/index.ts +15 -0
  107. package/src/module.ts +6 -0
  108. package/src/navigate.ts +51 -0
  109. package/src/router.ts +78 -0
  110. package/src/services/debug.ts +102 -0
  111. package/src/services/index.ts +2 -0
  112. package/src/store.ts +57 -0
  113. package/src/types.ts +72 -0
  114. package/src/utils/index.ts +4 -0
  115. package/src/utils/module.ts +14 -0
  116. package/src/utils/route.tsx +82 -0
  117. package/src/utils/router.ts +60 -0
  118. package/src/value.ts +60 -0
  119. package/tsconfig.json +15 -0
  120. package/tsconfig.tsbuildinfo +1 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 OwlMeans Common — Fullstack typescript framework
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,688 @@
1
+ # @owlmeans/client
2
+
3
+ A comprehensive React client library for OwlMeans Common applications. This package provides a complete foundation for building React-based frontend applications with integrated routing, state management, context handling, and component utilities.
4
+
5
+ ## Overview
6
+
7
+ The `@owlmeans/client` package extends the base `@owlmeans/client-context` package with React-specific functionality. It provides:
8
+
9
+ - **React Integration**: Complete React integration with hooks and context providers
10
+ - **Routing System**: Advanced routing with React Router integration and module-based navigation
11
+ - **Application Framework**: App component and router setup for complete applications
12
+ - **State Management**: Integrated state management with resource-based persistence
13
+ - **Context Management**: Enhanced client context with React-specific capabilities
14
+ - **UI Components**: Core UI components and utilities for React applications
15
+ - **Navigation Utilities**: Programmatic navigation and router interaction
16
+ - **Debug Services**: Development and debugging utilities
17
+
18
+ This package is designed for environment-agnostic React applications and can be extended with platform-specific implementations:
19
+ - **@owlmeans/web-client**: Web DOM-specific React implementation
20
+ - **@owlmeans/native-client**: React Native-specific implementation
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @owlmeans/client react react-router react-router-dom
26
+ ```
27
+
28
+ ## Core Concepts
29
+
30
+ ### Application Architecture
31
+ The library follows the OwlMeans pattern where modules represent URL units that can be transformed into React routes with associated components.
32
+
33
+ ### Context-Driven Development
34
+ All functionality is built around a central context that manages services, resources, modules, and application state.
35
+
36
+ ### Module-Based Routing
37
+ Routes are generated from modules, providing a unified approach to both frontend routing and backend API endpoints.
38
+
39
+ ## API Reference
40
+
41
+ ### Factory Functions
42
+
43
+ #### `makeClientContext<C, T>(cfg: C): T`
44
+
45
+ Creates an enhanced client context with React-specific capabilities.
46
+
47
+ ```typescript
48
+ import { makeClientContext } from '@owlmeans/client'
49
+ import { AppType, Layer } from '@owlmeans/context'
50
+
51
+ const context = makeClientContext({
52
+ service: 'my-app',
53
+ type: AppType.Frontend,
54
+ layer: Layer.Service,
55
+ ready: false,
56
+ services: {},
57
+ brand: {},
58
+ trusted: []
59
+ })
60
+ ```
61
+
62
+ **Parameters:**
63
+ - `cfg`: ClientConfig - Configuration object for the context
64
+
65
+ **Returns:** Enhanced ClientContext with React-specific capabilities
66
+
67
+ ### Core Interfaces
68
+
69
+ #### `ClientContext<C extends ClientConfig>`
70
+
71
+ Enhanced client context interface that extends BasicClientContext with React-specific functionality.
72
+
73
+ ```typescript
74
+ interface ClientContext<C extends ClientConfig = ClientConfig> extends BasicClientContext<C>,
75
+ ConfigResourceAppend,
76
+ StateResourceAppend,
77
+ ModalServiceAppend,
78
+ DebugServiceAppend {
79
+
80
+ // React-specific methods
81
+ registerRerenderer(listener: CallableFunction): () => void
82
+ rerender(): void
83
+ }
84
+ ```
85
+
86
+ **Enhanced Capabilities:**
87
+ - **Config Resource**: Configuration management and persistence
88
+ - **State Resource**: Application state management
89
+ - **Modal Service**: Modal dialog management
90
+ - **Debug Service**: Development and debugging utilities
91
+ - **Rerender System**: Component rerendering coordination
92
+
93
+ #### `RouterModel`
94
+
95
+ Interface for defining application routing structure.
96
+
97
+ ```typescript
98
+ interface RouterModel {
99
+ routes: RouteObject[]
100
+ resolve<C, T>(context: T): Promise<RouteObject[]>
101
+ }
102
+ ```
103
+
104
+ #### `Navigator`
105
+
106
+ Interface for programmatic navigation throughout the application.
107
+
108
+ ```typescript
109
+ interface Navigator {
110
+ _navigate: NavigateFunction
111
+ navigate<R>(module: ClientModule, request?: R): Promise<void>
112
+ go<R>(alias: string, request?: R): Promise<void>
113
+ back(): Promise<void>
114
+ pressBack(): () => void
115
+ }
116
+ ```
117
+
118
+ #### `NavRequest<T>`
119
+
120
+ Interface for navigation requests with additional client-specific options.
121
+
122
+ ```typescript
123
+ interface NavRequest<T = Record<string, any>> extends Partial<AbstractRequest<T>> {
124
+ replace?: boolean // Replace current route in history
125
+ silent?: boolean // Navigate without triggering side effects
126
+ }
127
+ ```
128
+
129
+ #### `ModuleContextParams<T>`
130
+
131
+ Parameters passed to route components when rendered.
132
+
133
+ ```typescript
134
+ interface ModuleContextParams<T = {}> {
135
+ alias: string // Module alias
136
+ params: AbstractRequest<T>['params'] // Route parameters
137
+ path: string // Current path
138
+ context: ClientContext // Application context
139
+ }
140
+ ```
141
+
142
+ #### `RoutedComponent<ExtraProps>`
143
+
144
+ Function component interface for route-rendered components.
145
+
146
+ ```typescript
147
+ interface RoutedComponent<ExtraProps = {}> extends FC<PropsWithChildren<ModuleContextParams & ExtraProps>> {
148
+ }
149
+ ```
150
+
151
+ ### React Components
152
+
153
+ #### `<App />`
154
+
155
+ Main application component that provides context and routing.
156
+
157
+ ```typescript
158
+ interface AppProps extends PropsWithChildren {
159
+ context: ClientContext<any>
160
+ provide?: RouterProvider | RemixRouter
161
+ }
162
+
163
+ const App: FC<AppProps>
164
+ ```
165
+
166
+ **Usage:**
167
+ ```typescript
168
+ import { App, makeClientContext } from '@owlmeans/client'
169
+
170
+ const context = makeClientContext(config)
171
+
172
+ function MyApp() {
173
+ return (
174
+ <App context={context} provide={routerProvider}>
175
+ <div>Application content</div>
176
+ </App>
177
+ )
178
+ }
179
+ ```
180
+
181
+ #### `<Router />`
182
+
183
+ Internal router component that manages React Router integration.
184
+
185
+ ```typescript
186
+ interface RouterProps {
187
+ provide: RouterProvider | RemixRouter
188
+ }
189
+
190
+ const Router: FC<RouterProps>
191
+ ```
192
+
193
+ **Note:** Usually used internally by the App component.
194
+
195
+ ### React Hooks
196
+
197
+ #### `useContext(): ClientContext`
198
+
199
+ Hook to access the application context from any component.
200
+
201
+ ```typescript
202
+ import { useContext } from '@owlmeans/client'
203
+
204
+ function MyComponent() {
205
+ const context = useContext()
206
+
207
+ // Access services
208
+ const authService = context.service('auth')
209
+
210
+ // Access resources
211
+ const stateResource = context.state()
212
+
213
+ return <div>Component content</div>
214
+ }
215
+ ```
216
+
217
+ ### Context Management
218
+
219
+ #### Enhanced Context Methods
220
+
221
+ The ClientContext provides additional methods beyond the basic context:
222
+
223
+ **`registerRerenderer(listener: CallableFunction): () => void`**
224
+ - **Purpose**: Register a listener for application-wide rerenders
225
+ - **Usage**: Component synchronization and global state updates
226
+ - **Returns**: Cleanup function to unregister the listener
227
+
228
+ **`rerender(): void`**
229
+ - **Purpose**: Trigger a rerender of all registered components
230
+ - **Usage**: Global state changes that require UI updates
231
+
232
+ ```typescript
233
+ const context = makeClientContext(config)
234
+
235
+ // Register for rerenders
236
+ const cleanup = context.registerRerenderer(() => {
237
+ console.log('Application rerendered')
238
+ })
239
+
240
+ // Trigger rerender
241
+ context.rerender()
242
+
243
+ // Cleanup when done
244
+ cleanup()
245
+ ```
246
+
247
+ ### Navigation System
248
+
249
+ #### Router Utilities
250
+
251
+ **`buildModuleTree(context: ClientContext): ModuleTree`**
252
+ Builds a tree structure from registered modules for routing.
253
+
254
+ **`initializeRouter(context: ClientContext): Promise<RouteObject[]>`**
255
+ Initializes the router with routes generated from modules.
256
+
257
+ **`createRouteRenderer(module: ClientModule): ComponentType`**
258
+ Creates a React component that renders the appropriate component for a module.
259
+
260
+ #### Navigation Methods
261
+
262
+ ```typescript
263
+ import { navigate, go, back } from '@owlmeans/client'
264
+
265
+ // Navigate to a specific module
266
+ await navigate(userModule, { params: { id: '123' } })
267
+
268
+ // Navigate by alias
269
+ await go('user-profile', { params: { id: '123' } })
270
+
271
+ // Go back in history
272
+ await back()
273
+ ```
274
+
275
+ ### State Management
276
+
277
+ The package integrates with `@owlmeans/state` for application state management:
278
+
279
+ ```typescript
280
+ // Access state resource
281
+ const stateResource = context.state()
282
+
283
+ // Save application state
284
+ await stateResource.save({
285
+ id: 'app-state',
286
+ data: { theme: 'dark', language: 'en' }
287
+ })
288
+
289
+ // Load application state
290
+ const state = await stateResource.load('app-state')
291
+ ```
292
+
293
+ ### Configuration Management
294
+
295
+ The package integrates with `@owlmeans/config` for configuration management:
296
+
297
+ ```typescript
298
+ // Access config resource
299
+ const configResource = context.config()
300
+
301
+ // Load configuration
302
+ const config = await configResource.load('app-config')
303
+ ```
304
+
305
+ ### Modal Management
306
+
307
+ Built-in modal service for managing dialogs:
308
+
309
+ ```typescript
310
+ // Access modal service
311
+ const modalService = context.modal()
312
+
313
+ // Show modal
314
+ modalService.show('confirm-dialog', {
315
+ title: 'Confirm Action',
316
+ message: 'Are you sure?'
317
+ })
318
+
319
+ // Hide modal
320
+ modalService.hide('confirm-dialog')
321
+ ```
322
+
323
+ ### Debug Service
324
+
325
+ Development and debugging utilities:
326
+
327
+ ```typescript
328
+ // Access debug service
329
+ const debugService = context.debug()
330
+
331
+ // Log debug information
332
+ debugService.log('module-routing', 'Route resolved', { alias: 'users' })
333
+
334
+ // Enable debug mode
335
+ debugService.enable('all')
336
+ ```
337
+
338
+ ### Utility Functions
339
+
340
+ #### Route Creation
341
+
342
+ **`createModuleRoute(module: ClientModule, component: ComponentType): RouteObject`**
343
+ Creates a React Router route object from a module and component.
344
+
345
+ **`resolveModulePath(module: ClientModule): string`**
346
+ Resolves the final path for a module considering parent relationships.
347
+
348
+ #### Component Utilities
349
+
350
+ **`withModuleContext(component: ComponentType): RoutedComponent`**
351
+ Higher-order component that injects module context into components.
352
+
353
+ ```typescript
354
+ import { withModuleContext } from '@owlmeans/client'
355
+
356
+ const UserProfile = withModuleContext(({ alias, params, context }) => {
357
+ const userId = params.id
358
+ return <div>User Profile for {userId}</div>
359
+ })
360
+ ```
361
+
362
+ ## Usage Examples
363
+
364
+ ### Basic Application Setup
365
+
366
+ ```typescript
367
+ import React from 'react'
368
+ import { createRoot } from 'react-dom/client'
369
+ import { App, makeClientContext } from '@owlmeans/client'
370
+ import { createBrowserRouter } from 'react-router-dom'
371
+ import { AppType, Layer } from '@owlmeans/context'
372
+
373
+ // Create application context
374
+ const context = makeClientContext({
375
+ service: 'my-app',
376
+ type: AppType.Frontend,
377
+ layer: Layer.Service,
378
+ ready: false,
379
+ services: {},
380
+ brand: { name: 'My App' },
381
+ trusted: []
382
+ })
383
+
384
+ // Register modules and services
385
+ context.registerModules(modules)
386
+ context.registerService(authService)
387
+
388
+ // Configure and initialize
389
+ await context.configure().init()
390
+
391
+ // Create router provider
392
+ const routerProvider = (routes) => createBrowserRouter(routes)
393
+
394
+ // Render application
395
+ const root = createRoot(document.getElementById('root'))
396
+ root.render(
397
+ <App context={context} provide={routerProvider}>
398
+ <header>My Application</header>
399
+ </App>
400
+ )
401
+ ```
402
+
403
+ ### Module-Based Routing
404
+
405
+ ```typescript
406
+ import { module, filter, body } from '@owlmeans/module'
407
+ import { route } from '@owlmeans/route'
408
+ import { UserProfile, UserList } from './components'
409
+
410
+ // Define modules with associated components
411
+ const userListModule = module(route('users', '/users'), {
412
+ component: UserList
413
+ })
414
+
415
+ const userProfileModule = module(
416
+ route('user-profile', '/users/:id'),
417
+ filter(params({
418
+ type: 'object',
419
+ properties: { id: { type: 'string' } },
420
+ required: ['id']
421
+ })),
422
+ { component: UserProfile }
423
+ )
424
+
425
+ // Register modules
426
+ context.registerModules([userListModule, userProfileModule])
427
+ ```
428
+
429
+ ### Programmatic Navigation
430
+
431
+ ```typescript
432
+ import { useContext, navigate, go } from '@owlmeans/client'
433
+
434
+ function NavigationExample() {
435
+ const context = useContext()
436
+
437
+ const handleUserClick = async (userId: string) => {
438
+ const userModule = context.module('user-profile')
439
+ await navigate(userModule, {
440
+ params: { id: userId },
441
+ replace: false
442
+ })
443
+ }
444
+
445
+ const handleBackClick = async () => {
446
+ await go('users')
447
+ }
448
+
449
+ return (
450
+ <div>
451
+ <button onClick={() => handleUserClick('123')}>
452
+ View User
453
+ </button>
454
+ <button onClick={handleBackClick}>
455
+ Back to Users
456
+ </button>
457
+ </div>
458
+ )
459
+ }
460
+ ```
461
+
462
+ ### Context Usage in Components
463
+
464
+ ```typescript
465
+ import { useContext } from '@owlmeans/client'
466
+
467
+ function UserDashboard() {
468
+ const context = useContext()
469
+
470
+ // Access services
471
+ const authService = context.service('auth')
472
+ const apiService = context.service('api')
473
+
474
+ // Access resources
475
+ const stateResource = context.state()
476
+ const configResource = context.config()
477
+
478
+ // Access utilities
479
+ const modalService = context.modal()
480
+ const debugService = context.debug()
481
+
482
+ const handleSaveState = async () => {
483
+ await stateResource.save({
484
+ id: 'dashboard-state',
485
+ data: { collapsed: false, activeTab: 'users' }
486
+ })
487
+ }
488
+
489
+ const handleShowModal = () => {
490
+ modalService.show('settings-modal')
491
+ }
492
+
493
+ return (
494
+ <div>
495
+ <h1>Dashboard</h1>
496
+ <button onClick={handleSaveState}>Save State</button>
497
+ <button onClick={handleShowModal}>Settings</button>
498
+ </div>
499
+ )
500
+ }
501
+ ```
502
+
503
+ ### Advanced Router Configuration
504
+
505
+ ```typescript
506
+ import { createBrowserRouter } from 'react-router-dom'
507
+ import { initializeRouter } from '@owlmeans/client'
508
+
509
+ // Custom router provider with error handling
510
+ const customRouterProvider = async (routes) => {
511
+ return createBrowserRouter(routes, {
512
+ future: {
513
+ v7_normalizeFormMethod: true
514
+ }
515
+ })
516
+ }
517
+
518
+ // Use with App component
519
+ <App context={context} provide={customRouterProvider}>
520
+ <ApplicationShell />
521
+ </App>
522
+ ```
523
+
524
+ ### Component with Module Context
525
+
526
+ ```typescript
527
+ import { RoutedComponent } from '@owlmeans/client'
528
+
529
+ const ProductDetails: RoutedComponent<{ extraProp: string }> = ({
530
+ alias,
531
+ params,
532
+ context,
533
+ extraProp
534
+ }) => {
535
+ const productId = params.id
536
+ const debugService = context.debug()
537
+
538
+ debugService.log('product-view', 'Viewing product', { productId })
539
+
540
+ return (
541
+ <div>
542
+ <h1>Product {productId}</h1>
543
+ <p>Extra prop: {extraProp}</p>
544
+ </div>
545
+ )
546
+ }
547
+ ```
548
+
549
+ ### State and Configuration Management
550
+
551
+ ```typescript
552
+ import { useContext } from '@owlmeans/client'
553
+ import { useEffect, useState } from 'react'
554
+
555
+ function AppSettings() {
556
+ const context = useContext()
557
+ const [settings, setSettings] = useState(null)
558
+
559
+ useEffect(() => {
560
+ const loadSettings = async () => {
561
+ const stateResource = context.state()
562
+ const saved = await stateResource.load('app-settings')
563
+ setSettings(saved?.data || { theme: 'light' })
564
+ }
565
+
566
+ loadSettings()
567
+ }, [])
568
+
569
+ const saveSettings = async (newSettings) => {
570
+ const stateResource = context.state()
571
+ await stateResource.save({
572
+ id: 'app-settings',
573
+ data: newSettings
574
+ })
575
+ setSettings(newSettings)
576
+ context.rerender() // Trigger global rerender if needed
577
+ }
578
+
579
+ return (
580
+ <div>
581
+ <h2>Settings</h2>
582
+ {settings && (
583
+ <div>
584
+ <label>
585
+ Theme:
586
+ <select
587
+ value={settings.theme}
588
+ onChange={(e) => saveSettings({ ...settings, theme: e.target.value })}
589
+ >
590
+ <option value="light">Light</option>
591
+ <option value="dark">Dark</option>
592
+ </select>
593
+ </label>
594
+ </div>
595
+ )}
596
+ </div>
597
+ )
598
+ }
599
+ ```
600
+
601
+ ## Error Handling
602
+
603
+ The package integrates with the OwlMeans error system:
604
+
605
+ ```typescript
606
+ import { OwlMeansError } from '@owlmeans/error'
607
+
608
+ // Error boundaries for React components
609
+ class AppErrorBoundary extends React.Component {
610
+ state = { hasError: false, error: null }
611
+
612
+ static getDerivedStateFromError(error) {
613
+ return { hasError: true, error }
614
+ }
615
+
616
+ componentDidCatch(error) {
617
+ const context = this.props.context
618
+ const debugService = context.debug()
619
+ debugService.error('app-error', 'Application error', error)
620
+ }
621
+
622
+ render() {
623
+ if (this.state.hasError) {
624
+ return <div>Something went wrong</div>
625
+ }
626
+ return this.props.children
627
+ }
628
+ }
629
+ ```
630
+
631
+ ## Performance Considerations
632
+
633
+ 1. **Context Optimization**: The context system is optimized for minimal re-renders
634
+ 2. **Lazy Loading**: Components and modules can be loaded on demand
635
+ 3. **State Persistence**: Application state is efficiently managed and persisted
636
+ 4. **Route Optimization**: Routes are generated efficiently from module definitions
637
+
638
+ ## Integration with Other Packages
639
+
640
+ ### Client Ecosystem
641
+ ```typescript
642
+ // Client authentication
643
+ import { makeAuthService } from '@owlmeans/client-auth'
644
+
645
+ // Client resources
646
+ import { makeResourceService } from '@owlmeans/client-resource'
647
+
648
+ // Client modules
649
+ import { modules } from '@owlmeans/client-module'
650
+ ```
651
+
652
+ ### Platform-Specific Extensions
653
+ ```typescript
654
+ // Web DOM implementation
655
+ import { makeWebClient } from '@owlmeans/web-client'
656
+
657
+ // React Native implementation
658
+ import { makeNativeClient } from '@owlmeans/native-client'
659
+ ```
660
+
661
+ ## Best Practices
662
+
663
+ 1. **Single Context**: Use one primary context per application
664
+ 2. **Module Organization**: Organize modules hierarchically for better route structure
665
+ 3. **State Management**: Use the integrated state resource for application state
666
+ 4. **Error Boundaries**: Implement error boundaries for robust error handling
667
+ 5. **Performance**: Leverage lazy loading for large applications
668
+ 6. **Context Access**: Use the provided hook rather than direct context access
669
+
670
+ ## Dependencies
671
+
672
+ This package depends on:
673
+ - `@owlmeans/client-context` - Basic client context functionality
674
+ - `@owlmeans/client-module` - Client-side module system
675
+ - `@owlmeans/client-resource` - Client-side resource management
676
+ - `@owlmeans/config` - Configuration management
677
+ - `@owlmeans/context` - Core context system
678
+ - `@owlmeans/state` - State management
679
+ - `react` - React library (peer dependency)
680
+ - `react-router` - React Router (peer dependency)
681
+
682
+ ## Related Packages
683
+
684
+ - [`@owlmeans/web-client`](../web-client) - Web DOM-specific React implementation
685
+ - [`@owlmeans/native-client`](../native-client) - React Native implementation
686
+ - [`@owlmeans/client-context`](../client-context) - Basic client context
687
+ - [`@owlmeans/client-module`](../client-module) - Client module system
688
+ - [`@owlmeans/client-auth`](../client-auth) - Client authentication
package/build/app.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { FC } from 'react';
2
+ import type { AppProps } from './types.js';
3
+ export declare const App: FC<AppProps>;
4
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAK1C,eAAO,MAAM,GAAG,EAAE,EAAE,CAAC,QAAQ,CAS5B,CAAA"}