@owlmeans/client 0.1.1 → 0.1.3
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/LICENSE +1 -1
- package/README.md +43 -641
- package/build/navigate.d.ts.map +1 -1
- package/build/navigate.js +14 -9
- package/build/navigate.js.map +1 -1
- package/build/types.d.ts +3 -3
- package/build/types.d.ts.map +1 -1
- package/build/utils/router.d.ts +3 -3
- package/build/utils/router.d.ts.map +1 -1
- package/build/utils/router.js +2 -2
- package/build/utils/router.js.map +1 -1
- package/build/value.d.ts +3 -0
- package/build/value.d.ts.map +1 -1
- package/build/value.js +3 -0
- package/build/value.js.map +1 -1
- package/package.json +15 -13
- package/src/navigate.ts +14 -10
- package/src/types.ts +3 -3
- package/src/utils/router.ts +8 -8
- package/src/value.ts +3 -0
- package/tsconfig.json +6 -10
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 OwlMeans Common — Fullstack typescript framework
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -1,687 +1,89 @@
|
|
|
1
1
|
# @owlmeans/client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Core React client framework providing hooks, context, navigation, and state management for OwlMeans frontends.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
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
|
|
7
|
+
- React hooks for subscribing to state stores (`useStoreModel`, `useStoreList`) and async data (`useValue`)
|
|
8
|
+
- `useNavigate()` — module-aware navigation that resolves URLs and calls the router
|
|
9
|
+
- `useContext()` — access the application's `ClientContext` from any React component
|
|
10
|
+
- `useToggle()` — boolean state toggle hook
|
|
11
|
+
- Used by every React frontend in the OwlMeans ecosystem
|
|
21
12
|
|
|
22
13
|
## Installation
|
|
23
14
|
|
|
24
15
|
```bash
|
|
25
|
-
|
|
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')
|
|
16
|
+
bun add @owlmeans/client
|
|
291
17
|
```
|
|
292
18
|
|
|
293
|
-
|
|
19
|
+
## Usage
|
|
294
20
|
|
|
295
|
-
|
|
21
|
+
Subscribe to a state store record:
|
|
296
22
|
|
|
297
23
|
```typescript
|
|
298
|
-
|
|
299
|
-
const configResource = context.config()
|
|
24
|
+
import { useStoreModel, useStoreList } from '@owlmeans/client'
|
|
300
25
|
|
|
301
|
-
|
|
302
|
-
const
|
|
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
|
-
)
|
|
26
|
+
function ProjectView({ projectId }: { projectId: string }) {
|
|
27
|
+
const model = useStoreModel<ProjectState>(projectId, 'project-state')
|
|
28
|
+
return <div>{model.record.title}</div>
|
|
459
29
|
}
|
|
460
30
|
```
|
|
461
31
|
|
|
462
|
-
|
|
32
|
+
Load async data:
|
|
463
33
|
|
|
464
34
|
```typescript
|
|
465
|
-
import {
|
|
35
|
+
import { useValue } from '@owlmeans/client'
|
|
466
36
|
|
|
467
|
-
function
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
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'
|
|
37
|
+
function StoryList({ projectId }: { projectId: string }) {
|
|
38
|
+
const stories = useValue(async () => {
|
|
39
|
+
return await ctx.story().list({ criteria: { projectId } })
|
|
40
|
+
}, [projectId])
|
|
528
41
|
|
|
529
|
-
|
|
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
|
-
)
|
|
42
|
+
return stories ? <List items={stories.items} /> : <Loading />
|
|
546
43
|
}
|
|
547
44
|
```
|
|
548
45
|
|
|
549
|
-
|
|
46
|
+
Navigate to a module:
|
|
550
47
|
|
|
551
48
|
```typescript
|
|
552
|
-
import {
|
|
553
|
-
import { useEffect, useState } from 'react'
|
|
49
|
+
import { useNavigate } from '@owlmeans/client'
|
|
554
50
|
|
|
555
|
-
function
|
|
556
|
-
const
|
|
557
|
-
|
|
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
|
-
)
|
|
51
|
+
function CreateButton() {
|
|
52
|
+
const navigate = useNavigate()
|
|
53
|
+
return <button onClick={() => navigate.go('project-create')}>Create</button>
|
|
598
54
|
}
|
|
599
55
|
```
|
|
600
56
|
|
|
601
|
-
##
|
|
602
|
-
|
|
603
|
-
The package integrates with the OwlMeans error system:
|
|
57
|
+
## API
|
|
604
58
|
|
|
605
|
-
|
|
606
|
-
import { OwlMeansError } from '@owlmeans/error'
|
|
59
|
+
### `useStoreModel<T>(id?, opts?): StateModel<T>`
|
|
607
60
|
|
|
608
|
-
|
|
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
|
-
```
|
|
61
|
+
Returns a single `StateModel` from a state resource. Creates the record if it doesn't exist.
|
|
630
62
|
|
|
631
|
-
|
|
63
|
+
### `useStoreList<T>(ids?, opts?): StateModel<T>[]`
|
|
632
64
|
|
|
633
|
-
|
|
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
|
|
65
|
+
Returns multiple `StateModel` instances from a state resource.
|
|
637
66
|
|
|
638
|
-
|
|
67
|
+
### `useValue<T>(loader, deps?, forceDefault?): T | null`
|
|
639
68
|
|
|
640
|
-
|
|
641
|
-
```typescript
|
|
642
|
-
// Client authentication
|
|
643
|
-
import { makeAuthService } from '@owlmeans/client-auth'
|
|
69
|
+
Async data loader hook. Re-runs when `deps` change. Returns `null` while loading.
|
|
644
70
|
|
|
645
|
-
|
|
646
|
-
import { makeResourceService } from '@owlmeans/client-resource'
|
|
71
|
+
### `useNavigate(): Navigator`
|
|
647
72
|
|
|
648
|
-
|
|
649
|
-
|
|
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
|
-
```
|
|
73
|
+
Returns a navigator with:
|
|
74
|
+
- `navigate(module, request?)` — navigate to a `ClientModule`
|
|
75
|
+
- `go(alias, request?)` — navigate by module alias
|
|
660
76
|
|
|
661
|
-
|
|
77
|
+
### `useContext<T>(): T`
|
|
662
78
|
|
|
663
|
-
|
|
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
|
|
79
|
+
Returns the current `ClientContext` cast to `T`.
|
|
669
80
|
|
|
670
|
-
|
|
81
|
+
### `useToggle(initial?): [boolean, () => void]`
|
|
671
82
|
|
|
672
|
-
|
|
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)
|
|
83
|
+
Simple boolean toggle hook.
|
|
680
84
|
|
|
681
85
|
## Related Packages
|
|
682
86
|
|
|
683
|
-
- [`@owlmeans/
|
|
684
|
-
- [`@owlmeans/
|
|
685
|
-
- [`@owlmeans/client-context`](../client-context)
|
|
686
|
-
- [`@owlmeans/client-module`](../client-module) - Client module system
|
|
687
|
-
- [`@owlmeans/client-auth`](../client-auth) - Client authentication
|
|
87
|
+
- [`@owlmeans/state`](../state) — `StateModel`, `StateResource` used by `useStoreModel`
|
|
88
|
+
- [`@owlmeans/client-module`](../client-module) — `ClientModule` used by `useNavigate`
|
|
89
|
+
- [`@owlmeans/client-context`](../client-context) — `ClientContext` returned by `useContext`
|
package/build/navigate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../src/navigate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAK3C,eAAO,MAAM,WAAW,QAAO,
|
|
1
|
+
{"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../src/navigate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAK3C,eAAO,MAAM,WAAW,QAAO,SA+C9B,CAAA"}
|
package/build/navigate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { EntrypointOutcome } from '@owlmeans/entrypoint';
|
|
3
3
|
import { useContext } from './context.js';
|
|
4
4
|
export const useNavigate = () => {
|
|
5
5
|
const context = useContext();
|
|
@@ -10,16 +10,21 @@ export const useNavigate = () => {
|
|
|
10
10
|
_navigate: navigate,
|
|
11
11
|
navigate: async (module, request) => {
|
|
12
12
|
const [url, ok] = await module.call(request);
|
|
13
|
-
if (ok ===
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
if (ok === EntrypointOutcome.Ok) {
|
|
14
|
+
if (url.startsWith('http')) {
|
|
15
|
+
globalThis.location.href = url;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
navigate(url, {
|
|
19
|
+
state: {
|
|
20
|
+
...module.route.route, silent: request?.silent
|
|
21
|
+
},
|
|
22
|
+
replace: request?.replace ?? false
|
|
23
|
+
});
|
|
24
|
+
}
|
|
20
25
|
}
|
|
21
26
|
},
|
|
22
|
-
go: async (alias, request) => navigator.navigate(context.
|
|
27
|
+
go: async (alias, request) => navigator.navigate(context.entrypoint(alias), request),
|
|
23
28
|
press: (alias, request) => () => {
|
|
24
29
|
void navigator.go(alias, request);
|
|
25
30
|
},
|
package/build/navigate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigate.js","sourceRoot":"","sources":["../src/navigate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"navigate.js","sourceRoot":"","sources":["../src/navigate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAGzC,MAAM,CAAC,MAAM,WAAW,GAAG,GAAc,EAAE;IACzC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAA;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAA;IAC/C,MAAM,SAAS,GAAc,OAAO,CAAC,GAAG,EAAE;QACxC,MAAM,SAAS,GAAc;YAC3B,SAAS,EAAE,QAAQ;YAEnB,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;gBAClC,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBAE5C,IAAI,EAAE,KAAK,iBAAiB,CAAC,EAAE,EAAE,CAAC;oBAChC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC3B,UAAU,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAA;oBAChC,CAAC;yBAAM,CAAC;wBACN,QAAQ,CAAC,GAAG,EAAE;4BACZ,KAAK,EAAE;gCACL,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;6BAC/C;4BACD,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,KAAK;yBACnC,CAAC,CAAA;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;YAED,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAC3B,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAA2B,KAAK,CAAC,EAAE,OAAO,CAAC;YAElF,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,GAAG,EAAE;gBAC9B,KAAK,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;YACnC,CAAC;YAED,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;YACd,CAAC;YAED,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE;gBACpB,KAAK,SAAS,CAAC,IAAI,EAAE,CAAA;YACvB,CAAC;YAED,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ;SACzB,CAAA;QAED,OAAO,SAAS,CAAA;IAClB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA"}
|
package/build/types.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { PropsWithChildren, FC, DependencyList } from 'react';
|
|
2
|
-
import type { AbstractRequest } from '@owlmeans/
|
|
2
|
+
import type { AbstractRequest } from '@owlmeans/entrypoint';
|
|
3
3
|
import type { ClientConfig, ClientContext as BasicClientContext } from '@owlmeans/client-context';
|
|
4
4
|
import type { StateResourceAppend } from '@owlmeans/state';
|
|
5
|
-
import type {
|
|
5
|
+
import type { ClientEntrypoint } from '@owlmeans/client-entrypoint';
|
|
6
6
|
import type { DebugServiceAppend, ModalServiceAppend } from './components/types.js';
|
|
7
7
|
import type { ConfigResourceAppend } from '@owlmeans/config';
|
|
8
8
|
import type { ConfigRecord } from '@owlmeans/context';
|
|
@@ -40,7 +40,7 @@ export interface NavRequest<T extends Record<string, any> = Record<string, any>>
|
|
|
40
40
|
}
|
|
41
41
|
export interface Navigator {
|
|
42
42
|
_navigate: NavigateFunction;
|
|
43
|
-
navigate: <R extends NavRequest = NavRequest>(module:
|
|
43
|
+
navigate: <R extends NavRequest = NavRequest>(module: ClientEntrypoint<string, AbstractRequest>, request?: R) => Promise<void>;
|
|
44
44
|
go: <R extends NavRequest = NavRequest>(alias: string, request?: R) => Promise<void>;
|
|
45
45
|
back: () => Promise<void>;
|
|
46
46
|
pressBack: () => () => void;
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/build/utils/router.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ClientEntrypoint } from '@owlmeans/client-entrypoint';
|
|
2
2
|
import type { ClientConfig } from '@owlmeans/client-context';
|
|
3
3
|
import type { ClientContext } from '../types.js';
|
|
4
4
|
type Config = ClientConfig;
|
|
@@ -8,9 +8,9 @@ export declare const buildModuleTree: <R, C extends Config = Config, T extends C
|
|
|
8
8
|
export declare const visitModuleTree: <T, R>(tree: ModuleTree<T>, visitor: ModuleTreeVisitor<T, R>) => Promise<R[]>;
|
|
9
9
|
export declare const initializeRouter: (context: Context) => Promise<unknown[]>;
|
|
10
10
|
export interface ModuleTreeVisitor<T, R> {
|
|
11
|
-
(module:
|
|
11
|
+
(module: ClientEntrypoint<T>, children: R[], alone: boolean): Promise<R>;
|
|
12
12
|
}
|
|
13
|
-
interface ModuleTree<T> extends Map<
|
|
13
|
+
interface ModuleTree<T> extends Map<ClientEntrypoint<T>, ModuleTree<T>> {
|
|
14
14
|
}
|
|
15
15
|
export {};
|
|
16
16
|
//# sourceMappingURL=router.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/utils/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/utils/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAGnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,KAAK,MAAM,GAAG,YAAY,CAAA;AAC1B,UAAU,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;CAAI;AAEzE,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,KAAG,UAAU,CAAC,CAAC,CA2BzH,CAAA;AAED,eAAO,MAAM,eAAe,GAAU,CAAC,EAAE,CAAC,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,EAAE,CAKpF,CAAA;AAE3B,eAAO,MAAM,gBAAgB,GAAU,SAAS,OAAO,uBAOtD,CAAA;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,EAAE,CAAC;IACrC,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CACzE;AAED,UAAU,UAAU,CAAC,CAAC,CAAE,SAAQ,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CACtE"}
|
package/build/utils/router.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AppType } from '@owlmeans/context';
|
|
2
2
|
import { makeRouterModel } from '../router.js';
|
|
3
3
|
export const buildModuleTree = (context) => {
|
|
4
|
-
const modules = context.
|
|
4
|
+
const modules = context.entrypoints().filter(module => module.route.route.type === AppType.Frontend
|
|
5
5
|
&& (module.sticky || module.route.route.service == null
|
|
6
6
|
|| module.route.route.service === context.cfg.service));
|
|
7
7
|
const flatTree = new Map();
|
|
@@ -12,7 +12,7 @@ export const buildModuleTree = (context) => {
|
|
|
12
12
|
roots.push(module);
|
|
13
13
|
}
|
|
14
14
|
else {
|
|
15
|
-
const parent = context.
|
|
15
|
+
const parent = context.entrypoint(parentAlias);
|
|
16
16
|
const list = flatTree.get(parent) ?? [];
|
|
17
17
|
list.push(module);
|
|
18
18
|
flatTree.set(parent, list);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/utils/router.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAO9C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAkE,OAAU,EAAiB,EAAE;IAC5H,MAAM,OAAO,GAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/utils/router.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAO9C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAkE,OAAU,EAAiB,EAAE;IAC5H,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAuB,CAAC,MAAM,CAC/D,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,QAAQ;WACjD,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI;eAClD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAC3D,CAAA;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8C,CAAA;IACtE,MAAM,KAAK,GAA0B,EAAE,CAAA;IAEvC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACvB,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,EAAE,CAAA;QAC3C,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACpB,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAsB,WAAW,CAAC,CAAA;YACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;YACvC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACjB,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,aAAa,GAAG,CAAC,OAA8B,EAAiB,EAAE,CAAC,OAAO,CAAC,MAAM,CACrF,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,GAAG,EAAE,CACzF,CAAA;IAED,OAAO,aAAa,CAAC,KAAK,CAAC,CAAA;AAC7B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAQ,IAAmB,EAAE,OAAgC,EAAgB,EAAE,CACjH,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAC/B,KAAK,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IAC3C,GAAG,CAAC,MAAM,MAAM,CAAC;IACjB,MAAM,OAAO,CAAC,MAAM,EAAE,MAAM,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;CACjF,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;AAE3B,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,OAAgB,EAAE,EAAE;IACzD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,CAAA;QAChC,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAA;IACpC,CAAC;IACD,MAAM,KAAK,GAAG,eAAe,EAAE,CAAA;IAC/B,OAAO,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;AACrC,CAAC,CAAA"}
|
package/build/value.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { MutableRefObject, DependencyList } from 'react';
|
|
2
2
|
import type { UseValueParams } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* @TODO add optional interface that doesn't return null if default value is not null
|
|
5
|
+
*/
|
|
3
6
|
export declare const useValue: <T>(loader: (cancel?: MutableRefObject<boolean>) => Promise<T>, def?: T | DependencyList | UseValueParams<T> | null, forceDefault?: boolean) => T | null;
|
|
4
7
|
//# sourceMappingURL=value.d.ts.map
|
package/build/value.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value.d.ts","sourceRoot":"","sources":["../src/value.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAIhD,eAAO,MAAM,QAAQ,GAAI,CAAC,EACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1D,MAAM,CAAC,GAAG,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,EACnD,eAAe,OAAO,KACrB,CAAC,GAAG,IAiDN,CAAA"}
|
|
1
|
+
{"version":3,"file":"value.d.ts","sourceRoot":"","sources":["../src/value.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAIhD;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,EACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1D,MAAM,CAAC,GAAG,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,EACnD,eAAe,OAAO,KACrB,CAAC,GAAG,IAiDN,CAAA"}
|
package/build/value.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { useEffect, useState, useRef, useId } from 'react';
|
|
2
2
|
const _complexValues = {};
|
|
3
|
+
/**
|
|
4
|
+
* @TODO add optional interface that doesn't return null if default value is not null
|
|
5
|
+
*/
|
|
3
6
|
export const useValue = (loader, def, forceDefault) => {
|
|
4
7
|
const deps = Array.isArray(def)
|
|
5
8
|
? def : typeof def === 'object' && def != null && 'deps' in def
|
package/build/value.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value.js","sourceRoot":"","sources":["../src/value.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAI1D,MAAM,cAAc,GAA2B,EAAE,CAAA;AAEjD,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,MAA0D,EAC1D,GAAmD,EACnD,YAAsB,EACZ,EAAE;IACZ,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAC7B,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,IAAI,IAAI,MAAM,IAAI,GAAG;QAC7D,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACzB,GAAG,GAAG,YAAY,KAAK,IAAI;QACzB,CAAC,CAAC,GAAe,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QACpC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,IAAI,IAAI,SAAS,IAAI,GAAG;QACjE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAe,CAAA;IACrC,MAAM,EAAE,GAAG,KAAK,EAAE,CAAA;IAClB,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAK,CAAA;IACrC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC,CAAA;IAE9D,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAE5B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACnD,MAAM,CAAC,OAAO,GAAG,KAAK,CAAA;YACtB,WAAW,CAAC,IAAI,CAAC,CAAA;QACnB,CAAC;QACD,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,OAAM;YACR,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAA;YAClC,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;gBAChC,cAAc,CAAC,EAAE,CAAC,GAAG,KAAK,CAAA;gBAC1B,QAAQ,CAAC,EAAS,CAAC,CAAA;YACrB,CAAC;iBAAM,CAAC;gBACN,IAAI,cAAc,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;oBAC/B,OAAO,cAAc,CAAC,EAAE,CAAC,CAAA;gBAC3B,CAAC;gBACD,QAAQ,CAAC,KAAK,CAAC,CAAA;YACjB,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;QAEJ,OAAO,GAAG,EAAE;YACV,IAAI,cAAc,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC/B,OAAO,cAAc,CAAC,EAAE,CAAC,CAAA;gBACzB,KAAK,GAAG,SAAS,CAAA;YACnB,CAAC;YACD,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;QACvB,CAAC,CAAA;IACH,CAAC,EAAE,IAAI,CAAC,CAAA;IAER,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE;QACvC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC;QACvB,CAAC,CAAC,KAAK,CACV,IAAI,GAAG,IAAI,IAAI,CAAA;AAClB,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"value.js","sourceRoot":"","sources":["../src/value.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAI1D,MAAM,cAAc,GAA2B,EAAE,CAAA;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,MAA0D,EAC1D,GAAmD,EACnD,YAAsB,EACZ,EAAE;IACZ,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAC7B,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,IAAI,IAAI,MAAM,IAAI,GAAG;QAC7D,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACzB,GAAG,GAAG,YAAY,KAAK,IAAI;QACzB,CAAC,CAAC,GAAe,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QACpC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,IAAI,IAAI,SAAS,IAAI,GAAG;QACjE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAe,CAAA;IACrC,MAAM,EAAE,GAAG,KAAK,EAAE,CAAA;IAClB,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAK,CAAA;IACrC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC,CAAA;IAE9D,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAE5B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACnD,MAAM,CAAC,OAAO,GAAG,KAAK,CAAA;YACtB,WAAW,CAAC,IAAI,CAAC,CAAA;QACnB,CAAC;QACD,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,OAAM;YACR,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAA;YAClC,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;gBAChC,cAAc,CAAC,EAAE,CAAC,GAAG,KAAK,CAAA;gBAC1B,QAAQ,CAAC,EAAS,CAAC,CAAA;YACrB,CAAC;iBAAM,CAAC;gBACN,IAAI,cAAc,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;oBAC/B,OAAO,cAAc,CAAC,EAAE,CAAC,CAAA;gBAC3B,CAAC;gBACD,QAAQ,CAAC,KAAK,CAAC,CAAA;YACjB,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;QAEJ,OAAO,GAAG,EAAE;YACV,IAAI,cAAc,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC/B,OAAO,cAAc,CAAC,EAAE,CAAC,CAAA;gBACzB,KAAK,GAAG,SAAS,CAAA;YACnB,CAAC;YACD,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;QACvB,CAAC,CAAA;IACH,CAAC,EAAE,IAAI,CAAC,CAAA;IAER,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE;QACvC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC;QACvB,CAAC,CAAC,KAAK,CACV,IAAI,GAAG,IAAI,IAAI,CAAA;AAClB,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"license": "MIT",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"scripts": {
|
|
6
7
|
"build": "tsc -b",
|
|
@@ -27,17 +28,17 @@
|
|
|
27
28
|
}
|
|
28
29
|
},
|
|
29
30
|
"dependencies": {
|
|
30
|
-
"@owlmeans/auth": "^0.1.
|
|
31
|
-
"@owlmeans/client-context": "^0.1.
|
|
32
|
-
"@owlmeans/client-
|
|
33
|
-
"@owlmeans/client-resource": "^0.1.
|
|
34
|
-
"@owlmeans/config": "^0.1.
|
|
35
|
-
"@owlmeans/context": "^0.1.
|
|
36
|
-
"@owlmeans/error": "^0.1.
|
|
37
|
-
"@owlmeans/
|
|
38
|
-
"@owlmeans/resource": "^0.1.
|
|
39
|
-
"@owlmeans/router": "^0.1.
|
|
40
|
-
"@owlmeans/state": "^0.1.
|
|
31
|
+
"@owlmeans/auth": "^0.1.3",
|
|
32
|
+
"@owlmeans/client-context": "^0.1.3",
|
|
33
|
+
"@owlmeans/client-entrypoint": "^0.1.3",
|
|
34
|
+
"@owlmeans/client-resource": "^0.1.3",
|
|
35
|
+
"@owlmeans/config": "^0.1.3",
|
|
36
|
+
"@owlmeans/context": "^0.1.3",
|
|
37
|
+
"@owlmeans/error": "^0.1.3",
|
|
38
|
+
"@owlmeans/entrypoint": "^0.1.3",
|
|
39
|
+
"@owlmeans/resource": "^0.1.3",
|
|
40
|
+
"@owlmeans/router": "^0.1.3",
|
|
41
|
+
"@owlmeans/state": "^0.1.3"
|
|
41
42
|
},
|
|
42
43
|
"peerDependencies": {
|
|
43
44
|
"@remix-run/router": "*",
|
|
@@ -49,10 +50,11 @@
|
|
|
49
50
|
}
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
53
|
+
"@owlmeans/dep-config": "workspace:*",
|
|
52
54
|
"@types/react": "^19.2.7",
|
|
53
55
|
"nodemon": "^3.1.11",
|
|
54
56
|
"npm-check": "^6.0.1",
|
|
55
|
-
"typescript": "^
|
|
57
|
+
"typescript": "^6.0.2"
|
|
56
58
|
},
|
|
57
59
|
"publishConfig": {
|
|
58
60
|
"access": "public"
|
package/src/navigate.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useMemo } from 'react'
|
|
2
2
|
import type { Navigator } from './types.js'
|
|
3
|
-
import {
|
|
3
|
+
import { EntrypointOutcome } from '@owlmeans/entrypoint'
|
|
4
4
|
import { useContext } from './context.js'
|
|
5
|
-
import type {
|
|
5
|
+
import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
|
|
6
6
|
|
|
7
7
|
export const useNavigate = (): Navigator => {
|
|
8
8
|
const context = useContext()
|
|
@@ -15,18 +15,22 @@ export const useNavigate = (): Navigator => {
|
|
|
15
15
|
navigate: async (module, request) => {
|
|
16
16
|
const [url, ok] = await module.call(request)
|
|
17
17
|
|
|
18
|
-
if (ok ===
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
if (ok === EntrypointOutcome.Ok) {
|
|
19
|
+
if (url.startsWith('http')) {
|
|
20
|
+
globalThis.location.href = url
|
|
21
|
+
} else {
|
|
22
|
+
navigate(url, {
|
|
23
|
+
state: {
|
|
24
|
+
...module.route.route, silent: request?.silent
|
|
25
|
+
},
|
|
26
|
+
replace: request?.replace ?? false
|
|
27
|
+
})
|
|
28
|
+
}
|
|
25
29
|
}
|
|
26
30
|
},
|
|
27
31
|
|
|
28
32
|
go: async (alias, request) =>
|
|
29
|
-
navigator.navigate(context.
|
|
33
|
+
navigator.navigate(context.entrypoint<ClientEntrypoint<string>>(alias), request),
|
|
30
34
|
|
|
31
35
|
press: (alias, request) => () => {
|
|
32
36
|
void navigator.go(alias, request)
|
package/src/types.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { PropsWithChildren, FC, DependencyList } from 'react'
|
|
2
|
-
import type { AbstractRequest } from '@owlmeans/
|
|
2
|
+
import type { AbstractRequest } from '@owlmeans/entrypoint'
|
|
3
3
|
import type { ClientConfig, ClientContext as BasicClientContext } from '@owlmeans/client-context'
|
|
4
4
|
import type { StateResourceAppend } from '@owlmeans/state'
|
|
5
|
-
import type {
|
|
5
|
+
import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
|
|
6
6
|
import type { DebugServiceAppend, ModalServiceAppend } from './components/types.js'
|
|
7
7
|
import type { ConfigResourceAppend } from '@owlmeans/config'
|
|
8
8
|
import type { ConfigRecord } from '@owlmeans/context'
|
|
@@ -55,7 +55,7 @@ export interface NavRequest<T extends Record<string, any> = Record<string, any>>
|
|
|
55
55
|
|
|
56
56
|
export interface Navigator {
|
|
57
57
|
_navigate: NavigateFunction
|
|
58
|
-
navigate: <R extends NavRequest = NavRequest>(module:
|
|
58
|
+
navigate: <R extends NavRequest = NavRequest>(module: ClientEntrypoint<string, AbstractRequest>, request?: R) => Promise<void>
|
|
59
59
|
go: <R extends NavRequest = NavRequest>(alias: string, request?: R) => Promise<void>
|
|
60
60
|
back: () => Promise<void>
|
|
61
61
|
pressBack: () => () => void
|
package/src/utils/router.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
|
|
2
2
|
import { AppType } from '@owlmeans/context'
|
|
3
3
|
import { makeRouterModel } from '../router.js'
|
|
4
4
|
import type { ClientConfig } from '@owlmeans/client-context'
|
|
@@ -8,28 +8,28 @@ type Config = ClientConfig
|
|
|
8
8
|
interface Context<C extends Config = Config> extends ClientContext<C> { }
|
|
9
9
|
|
|
10
10
|
export const buildModuleTree = <R, C extends Config = Config, T extends Context<C> = Context<C>>(context: T): ModuleTree<R> => {
|
|
11
|
-
const modules = context.
|
|
11
|
+
const modules = context.entrypoints<ClientEntrypoint<R>>().filter(
|
|
12
12
|
module => module.route.route.type === AppType.Frontend
|
|
13
13
|
&& (module.sticky || module.route.route.service == null
|
|
14
14
|
|| module.route.route.service === context.cfg.service)
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
-
const flatTree = new Map<
|
|
18
|
-
const roots:
|
|
17
|
+
const flatTree = new Map<ClientEntrypoint<R>, ClientEntrypoint<R>[]>()
|
|
18
|
+
const roots: ClientEntrypoint<R>[] = []
|
|
19
19
|
|
|
20
20
|
modules.forEach(module => {
|
|
21
21
|
const parentAlias = module.getParentAlias()
|
|
22
22
|
if (parentAlias == null) {
|
|
23
23
|
roots.push(module)
|
|
24
24
|
} else {
|
|
25
|
-
const parent = context.
|
|
25
|
+
const parent = context.entrypoint<ClientEntrypoint<R>>(parentAlias)
|
|
26
26
|
const list = flatTree.get(parent) ?? []
|
|
27
27
|
list.push(module)
|
|
28
28
|
flatTree.set(parent, list)
|
|
29
29
|
}
|
|
30
30
|
})
|
|
31
31
|
|
|
32
|
-
const reduceModules = (modules:
|
|
32
|
+
const reduceModules = (modules: ClientEntrypoint<R>[]): ModuleTree<R> => modules.reduce(
|
|
33
33
|
(tree, module) => tree.set(module, reduceModules(flatTree.get(module) ?? [])), new Map()
|
|
34
34
|
)
|
|
35
35
|
|
|
@@ -53,8 +53,8 @@ export const initializeRouter = async (context: Context) => {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export interface ModuleTreeVisitor<T, R> {
|
|
56
|
-
(module:
|
|
56
|
+
(module: ClientEntrypoint<T>, children: R[], alone: boolean): Promise<R>
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
interface ModuleTree<T> extends Map<
|
|
59
|
+
interface ModuleTree<T> extends Map<ClientEntrypoint<T>, ModuleTree<T>> {
|
|
60
60
|
}
|
package/src/value.ts
CHANGED
|
@@ -4,6 +4,9 @@ import type { UseValueParams } from './types.js'
|
|
|
4
4
|
|
|
5
5
|
const _complexValues: { [key: string]: any } = {}
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @TODO add optional interface that doesn't return null if default value is not null
|
|
9
|
+
*/
|
|
7
10
|
export const useValue = <T>(
|
|
8
11
|
loader: (cancel?: MutableRefObject<boolean>) => Promise<T>,
|
|
9
12
|
def?: T | DependencyList | UseValueParams<T> | null,
|
package/tsconfig.json
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extends": [
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"@owlmeans/dep-config/tsconfig.base.json",
|
|
4
|
+
"@owlmeans/dep-config/tsconfig.react.json"
|
|
5
5
|
],
|
|
6
6
|
"compilerOptions": {
|
|
7
|
-
"rootDir": "./src/",
|
|
8
|
-
"outDir": "./build/"
|
|
7
|
+
"rootDir": "./src/",
|
|
8
|
+
"outDir": "./build/"
|
|
9
9
|
},
|
|
10
|
-
"exclude": [
|
|
11
|
-
|
|
12
|
-
"./build/**/*",
|
|
13
|
-
"./*.ts"
|
|
14
|
-
]
|
|
15
|
-
}
|
|
10
|
+
"exclude": ["./dist/**/*", "./build/**/*", "./*.ts"]
|
|
11
|
+
}
|