@owlmeans/web-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.
- package/LICENSE +21 -0
- package/README.md +617 -0
- package/build/components/dispatcher/component.d.ts +2 -0
- package/build/components/dispatcher/component.d.ts.map +1 -0
- package/build/components/dispatcher/component.js +41 -0
- package/build/components/dispatcher/component.js.map +1 -0
- package/build/components/dispatcher/index.d.ts +2 -0
- package/build/components/dispatcher/index.d.ts.map +1 -0
- package/build/components/dispatcher/index.js +2 -0
- package/build/components/dispatcher/index.js.map +1 -0
- package/build/components/index.d.ts +3 -0
- package/build/components/index.d.ts.map +1 -0
- package/build/components/index.js +3 -0
- package/build/components/index.js.map +1 -0
- package/build/components/uploader/component.d.ts +4 -0
- package/build/components/uploader/component.d.ts.map +1 -0
- package/build/components/uploader/component.js +10 -0
- package/build/components/uploader/component.js.map +1 -0
- package/build/components/uploader/image.d.ts +4 -0
- package/build/components/uploader/image.d.ts.map +1 -0
- package/build/components/uploader/image.js +8 -0
- package/build/components/uploader/image.js.map +1 -0
- package/build/components/uploader/index.d.ts +4 -0
- package/build/components/uploader/index.d.ts.map +1 -0
- package/build/components/uploader/index.js +3 -0
- package/build/components/uploader/index.js.map +1 -0
- package/build/components/uploader/types.d.ts +13 -0
- package/build/components/uploader/types.d.ts.map +1 -0
- package/build/components/uploader/types.js +2 -0
- package/build/components/uploader/types.js.map +1 -0
- package/build/consts.d.ts +2 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +2 -0
- package/build/consts.js.map +1 -0
- package/build/context.d.ts +4 -0
- package/build/context.d.ts.map +1 -0
- package/build/context.js +18 -0
- package/build/context.js.map +1 -0
- package/build/errors.d.ts +11 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +19 -0
- package/build/errors.js.map +1 -0
- package/build/exports.d.ts +9 -0
- package/build/exports.d.ts.map +1 -0
- package/build/exports.js +7 -0
- package/build/exports.js.map +1 -0
- package/build/helper.d.ts +3 -0
- package/build/helper.d.ts.map +1 -0
- package/build/helper.js +7 -0
- package/build/helper.js.map +1 -0
- package/build/i18n/auth-en.json +5 -0
- package/build/i18n.d.ts +2 -0
- package/build/i18n.d.ts.map +1 -0
- package/build/i18n.js +4 -0
- package/build/i18n.js.map +1 -0
- package/build/index.d.ts +13 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +13 -0
- package/build/index.js.map +1 -0
- package/build/main.d.ts +4 -0
- package/build/main.d.ts.map +1 -0
- package/build/main.js +22 -0
- package/build/main.js.map +1 -0
- package/build/modules.d.ts +2 -0
- package/build/modules.d.ts.map +1 -0
- package/build/modules.js +8 -0
- package/build/modules.js.map +1 -0
- package/build/router.d.ts +3 -0
- package/build/router.d.ts.map +1 -0
- package/build/router.js +5 -0
- package/build/router.js.map +1 -0
- package/build/service.d.ts +6 -0
- package/build/service.d.ts.map +1 -0
- package/build/service.js +26 -0
- package/build/service.js.map +1 -0
- package/build/types.d.ts +14 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/package.json +57 -0
- package/src/components/dispatcher/component.tsx +43 -0
- package/src/components/dispatcher/index.ts +2 -0
- package/src/components/index.ts +3 -0
- package/src/components/uploader/component.tsx +17 -0
- package/src/components/uploader/image.tsx +10 -0
- package/src/components/uploader/index.ts +4 -0
- package/src/components/uploader/types.ts +14 -0
- package/src/consts.ts +2 -0
- package/src/context.ts +27 -0
- package/src/errors.ts +25 -0
- package/src/exports.ts +9 -0
- package/src/helper.ts +8 -0
- package/src/i18n/auth-en.json +5 -0
- package/src/i18n.ts +5 -0
- package/src/index.ts +13 -0
- package/src/main.tsx +25 -0
- package/src/modules.ts +9 -0
- package/src/router.ts +7 -0
- package/src/service.ts +41 -0
- package/src/types.ts +17 -0
- package/tsconfig.json +15 -0
- 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,617 @@
|
|
|
1
|
+
# @owlmeans/web-client
|
|
2
|
+
|
|
3
|
+
A complete React DOM client library for OwlMeans Common applications. This package provides a web-specific implementation that extends `@owlmeans/client` with DOM-specific functionality, including rendering utilities, web database integration, and browser-specific services.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `@owlmeans/web-client` package is the web DOM implementation of the OwlMeans client system. It provides:
|
|
8
|
+
|
|
9
|
+
- **DOM Rendering**: Direct integration with ReactDOM for web applications
|
|
10
|
+
- **Web Database**: Browser-based database integration with IndexedDB/localStorage
|
|
11
|
+
- **Authentication Integration**: Pre-configured web authentication services
|
|
12
|
+
- **Browser Services**: Web-specific services and utilities
|
|
13
|
+
- **I18n Integration**: Internationalization support for web applications
|
|
14
|
+
- **Router Integration**: Web-specific routing with React Router DOM
|
|
15
|
+
- **Context Management**: Enhanced context with web-specific capabilities
|
|
16
|
+
|
|
17
|
+
This package is part of the OwlMeans client implementation family:
|
|
18
|
+
- **@owlmeans/client**: Base React client library
|
|
19
|
+
- **@owlmeans/web-client**: Web DOM implementation *(this package)*
|
|
20
|
+
- **@owlmeans/native-client**: React Native implementation
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @owlmeans/web-client react react-dom react-router-dom
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Core Concepts
|
|
29
|
+
|
|
30
|
+
### Web-First Architecture
|
|
31
|
+
This library is specifically designed for web browsers and provides DOM-specific functionality that isn't available in other environments.
|
|
32
|
+
|
|
33
|
+
### Enhanced Context
|
|
34
|
+
The web context extends the base client context with web-specific services like database storage, authentication, and browser utilities.
|
|
35
|
+
|
|
36
|
+
### Integrated Rendering
|
|
37
|
+
Provides seamless integration with ReactDOM including support for both client-side rendering and server-side hydration.
|
|
38
|
+
|
|
39
|
+
## API Reference
|
|
40
|
+
|
|
41
|
+
### Factory Functions
|
|
42
|
+
|
|
43
|
+
#### `makeContext<C, T>(cfg: C): T`
|
|
44
|
+
|
|
45
|
+
Creates a web-specific application context with all necessary web services pre-configured.
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { makeContext } from '@owlmeans/web-client'
|
|
49
|
+
import { AppType, Layer } from '@owlmeans/context'
|
|
50
|
+
|
|
51
|
+
const context = makeContext({
|
|
52
|
+
service: 'my-web-app',
|
|
53
|
+
type: AppType.Frontend,
|
|
54
|
+
layer: Layer.Service,
|
|
55
|
+
ready: false,
|
|
56
|
+
services: {},
|
|
57
|
+
brand: { name: 'My Web App' },
|
|
58
|
+
trusted: []
|
|
59
|
+
})
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Parameters:**
|
|
63
|
+
- `cfg`: AppConfig - Configuration object for the web context
|
|
64
|
+
|
|
65
|
+
**Returns:** Enhanced AppContext with web-specific capabilities
|
|
66
|
+
|
|
67
|
+
**Pre-configured Services:**
|
|
68
|
+
- Web authentication service
|
|
69
|
+
- Web database service
|
|
70
|
+
- Client resource service
|
|
71
|
+
- Primary host extraction
|
|
72
|
+
|
|
73
|
+
#### `render(node: ReactNode, opts?: RenderOptions): void`
|
|
74
|
+
|
|
75
|
+
Renders a React application to the DOM with web-specific optimizations.
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { render } from '@owlmeans/web-client'
|
|
79
|
+
import { App } from '@owlmeans/client'
|
|
80
|
+
|
|
81
|
+
render(
|
|
82
|
+
<App context={context}>
|
|
83
|
+
<MyApplication />
|
|
84
|
+
</App>,
|
|
85
|
+
{
|
|
86
|
+
domId: 'root',
|
|
87
|
+
onReady: true,
|
|
88
|
+
hydrate: false,
|
|
89
|
+
debug: true
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Parameters:**
|
|
95
|
+
- `node`: ReactNode - The React element to render
|
|
96
|
+
- `opts`: RenderOptions (optional) - Rendering configuration
|
|
97
|
+
|
|
98
|
+
### Core Interfaces
|
|
99
|
+
|
|
100
|
+
#### `AppContext<C extends AppConfig>`
|
|
101
|
+
|
|
102
|
+
Web-specific application context that extends ClientContext with authentication capabilities.
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
interface AppContext<C extends AppConfig = AppConfig> extends ClientContext<C>,
|
|
106
|
+
AuthServiceAppend {
|
|
107
|
+
|
|
108
|
+
// Inherited from ClientContext:
|
|
109
|
+
// - Configuration management
|
|
110
|
+
// - State management
|
|
111
|
+
// - Modal service
|
|
112
|
+
// - Debug service
|
|
113
|
+
// - Module and service registration
|
|
114
|
+
// - Resource management
|
|
115
|
+
|
|
116
|
+
// Enhanced with authentication:
|
|
117
|
+
auth(): AuthService
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### `AppConfig`
|
|
122
|
+
|
|
123
|
+
Configuration interface for web applications (extends ClientConfig).
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
interface AppConfig extends ClientConfig {
|
|
127
|
+
// Inherits all ClientConfig properties
|
|
128
|
+
// Can be extended with web-specific configuration
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### `RenderOptions`
|
|
133
|
+
|
|
134
|
+
Configuration options for DOM rendering.
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
interface RenderOptions {
|
|
138
|
+
domId?: string // Target DOM element ID (default: 'root')
|
|
139
|
+
onReady?: boolean // Wait for DOMContentLoaded (default: true)
|
|
140
|
+
hydrate?: boolean // Use hydration for SSR (default: false)
|
|
141
|
+
debug?: boolean // Enable debug logging (default: false)
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### React Hooks
|
|
146
|
+
|
|
147
|
+
#### `useContext<C, T>(): T`
|
|
148
|
+
|
|
149
|
+
Web-specific context hook that provides strongly typed access to the AppContext.
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { useContext } from '@owlmeans/web-client'
|
|
153
|
+
|
|
154
|
+
function MyWebComponent() {
|
|
155
|
+
const context = useContext()
|
|
156
|
+
|
|
157
|
+
// Access web-specific services
|
|
158
|
+
const authService = context.auth()
|
|
159
|
+
const dbService = context.service('web-db')
|
|
160
|
+
|
|
161
|
+
// Access base client services
|
|
162
|
+
const stateResource = context.state()
|
|
163
|
+
const modalService = context.modal()
|
|
164
|
+
|
|
165
|
+
return <div>Web Component</div>
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Web Services
|
|
170
|
+
|
|
171
|
+
#### Web Database Integration
|
|
172
|
+
|
|
173
|
+
The package automatically configures web database services:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// Access web database service
|
|
177
|
+
const dbService = context.service('web-db')
|
|
178
|
+
|
|
179
|
+
// Store data in browser
|
|
180
|
+
await dbService.store('user-preferences', {
|
|
181
|
+
theme: 'dark',
|
|
182
|
+
language: 'en'
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
// Retrieve data from browser
|
|
186
|
+
const preferences = await dbService.retrieve('user-preferences')
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Authentication Service
|
|
190
|
+
|
|
191
|
+
Pre-configured web authentication with persistent storage:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// Access authentication service
|
|
195
|
+
const authService = context.auth()
|
|
196
|
+
|
|
197
|
+
// Authentication persists across browser sessions
|
|
198
|
+
const isAuthenticated = await authService.authenticated()
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Helper Functions
|
|
202
|
+
|
|
203
|
+
#### `extractPrimaryHost<C, T>(context: T): void`
|
|
204
|
+
|
|
205
|
+
Extracts and configures the primary host from the current browser location.
|
|
206
|
+
|
|
207
|
+
**Purpose**: Automatically configures the application's primary host based on the browser's current URL
|
|
208
|
+
|
|
209
|
+
**Usage**: Called automatically during context creation
|
|
210
|
+
|
|
211
|
+
### Constants
|
|
212
|
+
|
|
213
|
+
#### `DEFAULT_ROOT`
|
|
214
|
+
Default DOM element ID for rendering (`'root'`).
|
|
215
|
+
|
|
216
|
+
### Components and Modules
|
|
217
|
+
|
|
218
|
+
The package provides web-specific components and modules:
|
|
219
|
+
|
|
220
|
+
#### I18n Integration
|
|
221
|
+
```typescript
|
|
222
|
+
import { i18nModules } from '@owlmeans/web-client'
|
|
223
|
+
|
|
224
|
+
// Pre-configured internationalization modules
|
|
225
|
+
context.registerModules(i18nModules)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
#### Authentication Components
|
|
229
|
+
```typescript
|
|
230
|
+
import { authComponents } from '@owlmeans/web-client'
|
|
231
|
+
|
|
232
|
+
// Web-specific authentication components
|
|
233
|
+
// Available through the component system
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Usage Examples
|
|
237
|
+
|
|
238
|
+
### Complete Web Application Setup
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
import React from 'react'
|
|
242
|
+
import { makeContext, render } from '@owlmeans/web-client'
|
|
243
|
+
import { App } from '@owlmeans/client'
|
|
244
|
+
import { createBrowserRouter } from 'react-router-dom'
|
|
245
|
+
import { AppType, Layer } from '@owlmeans/context'
|
|
246
|
+
|
|
247
|
+
// Create web application context
|
|
248
|
+
const context = makeContext({
|
|
249
|
+
service: 'my-web-app',
|
|
250
|
+
type: AppType.Frontend,
|
|
251
|
+
layer: Layer.Service,
|
|
252
|
+
ready: false,
|
|
253
|
+
services: {},
|
|
254
|
+
brand: {
|
|
255
|
+
name: 'My Web App',
|
|
256
|
+
version: '1.0.0'
|
|
257
|
+
},
|
|
258
|
+
trusted: ['api.myapp.com']
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
// Register application modules
|
|
262
|
+
context.registerModules(appModules)
|
|
263
|
+
|
|
264
|
+
// Configure and initialize
|
|
265
|
+
await context.configure().init()
|
|
266
|
+
|
|
267
|
+
// Create router provider
|
|
268
|
+
const routerProvider = (routes) => createBrowserRouter(routes)
|
|
269
|
+
|
|
270
|
+
// Define the application
|
|
271
|
+
function MyWebApp() {
|
|
272
|
+
return (
|
|
273
|
+
<App context={context} provide={routerProvider}>
|
|
274
|
+
<header>My Web Application</header>
|
|
275
|
+
<main>
|
|
276
|
+
{/* Application content will be rendered here by the router */}
|
|
277
|
+
</main>
|
|
278
|
+
</App>
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Render to DOM
|
|
283
|
+
render(<MyWebApp />, {
|
|
284
|
+
domId: 'root',
|
|
285
|
+
debug: process.env.NODE_ENV === 'development'
|
|
286
|
+
})
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Server-Side Rendering (SSR) with Hydration
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
import { makeContext, render } from '@owlmeans/web-client'
|
|
293
|
+
import { App } from '@owlmeans/client'
|
|
294
|
+
|
|
295
|
+
// Create context with SSR data
|
|
296
|
+
const context = makeContext({
|
|
297
|
+
...config,
|
|
298
|
+
ssrData: window.__SSR_DATA__ // Data from server
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
// Pre-populate context with SSR data
|
|
302
|
+
await context.configure().init()
|
|
303
|
+
|
|
304
|
+
// Hydrate the server-rendered HTML
|
|
305
|
+
render(
|
|
306
|
+
<App context={context}>
|
|
307
|
+
<MyApplication />
|
|
308
|
+
</App>,
|
|
309
|
+
{
|
|
310
|
+
hydrate: true, // Enable hydration
|
|
311
|
+
onReady: false // Don't wait for DOMContentLoaded
|
|
312
|
+
}
|
|
313
|
+
)
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Authentication-Enabled Web App
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
import { makeContext, useContext } from '@owlmeans/web-client'
|
|
320
|
+
import { modules as authModules } from '@owlmeans/client-auth'
|
|
321
|
+
|
|
322
|
+
// Create context
|
|
323
|
+
const context = makeContext(config)
|
|
324
|
+
|
|
325
|
+
// Register authentication modules
|
|
326
|
+
context.registerModules(authModules)
|
|
327
|
+
|
|
328
|
+
// Initialize
|
|
329
|
+
await context.configure().init()
|
|
330
|
+
|
|
331
|
+
function AuthenticatedApp() {
|
|
332
|
+
const context = useContext()
|
|
333
|
+
const [isAuthenticated, setIsAuthenticated] = useState(false)
|
|
334
|
+
|
|
335
|
+
useEffect(() => {
|
|
336
|
+
const checkAuth = async () => {
|
|
337
|
+
const authService = context.auth()
|
|
338
|
+
const token = await authService.authenticated()
|
|
339
|
+
setIsAuthenticated(token != null)
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
checkAuth()
|
|
343
|
+
}, [])
|
|
344
|
+
|
|
345
|
+
if (!isAuthenticated) {
|
|
346
|
+
return <LoginPage />
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return <Dashboard />
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Render with authentication
|
|
353
|
+
render(<AuthenticatedApp />)
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Web Database Usage
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
import { useContext } from '@owlmeans/web-client'
|
|
360
|
+
import { useEffect, useState } from 'react'
|
|
361
|
+
|
|
362
|
+
function DataPersistentComponent() {
|
|
363
|
+
const context = useContext()
|
|
364
|
+
const [data, setData] = useState(null)
|
|
365
|
+
|
|
366
|
+
useEffect(() => {
|
|
367
|
+
const loadData = async () => {
|
|
368
|
+
// Access web database through context
|
|
369
|
+
const dbService = context.service('web-db')
|
|
370
|
+
|
|
371
|
+
// Load persisted data
|
|
372
|
+
const savedData = await dbService.retrieve('component-data')
|
|
373
|
+
setData(savedData || { count: 0 })
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
loadData()
|
|
377
|
+
}, [])
|
|
378
|
+
|
|
379
|
+
const saveData = async (newData) => {
|
|
380
|
+
const dbService = context.service('web-db')
|
|
381
|
+
await dbService.store('component-data', newData)
|
|
382
|
+
setData(newData)
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const increment = () => {
|
|
386
|
+
const newData = { count: data.count + 1 }
|
|
387
|
+
saveData(newData)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return (
|
|
391
|
+
<div>
|
|
392
|
+
<p>Count: {data?.count || 0}</p>
|
|
393
|
+
<button onClick={increment}>Increment</button>
|
|
394
|
+
</div>
|
|
395
|
+
)
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Custom Rendering Options
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
import { render } from '@owlmeans/web-client'
|
|
403
|
+
|
|
404
|
+
// Render to custom DOM element
|
|
405
|
+
render(<MyApp />, {
|
|
406
|
+
domId: 'custom-root',
|
|
407
|
+
debug: true
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
// Immediate rendering (don't wait for DOMContentLoaded)
|
|
411
|
+
render(<MyApp />, {
|
|
412
|
+
onReady: false
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
// Server-side hydration
|
|
416
|
+
render(<MyApp />, {
|
|
417
|
+
hydrate: true,
|
|
418
|
+
onReady: false
|
|
419
|
+
})
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Advanced Context Configuration
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import { makeContext } from '@owlmeans/web-client'
|
|
426
|
+
|
|
427
|
+
const context = makeContext({
|
|
428
|
+
service: 'advanced-app',
|
|
429
|
+
type: AppType.Frontend,
|
|
430
|
+
layer: Layer.Service,
|
|
431
|
+
ready: false,
|
|
432
|
+
|
|
433
|
+
// Web-specific configuration
|
|
434
|
+
services: {
|
|
435
|
+
database: {
|
|
436
|
+
type: 'indexeddb',
|
|
437
|
+
name: 'my-app-db'
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
|
|
441
|
+
// Branding
|
|
442
|
+
brand: {
|
|
443
|
+
name: 'Advanced Web App',
|
|
444
|
+
version: '2.1.0',
|
|
445
|
+
logo: '/assets/logo.png'
|
|
446
|
+
},
|
|
447
|
+
|
|
448
|
+
// Trusted hosts for API calls
|
|
449
|
+
trusted: [
|
|
450
|
+
'api.myapp.com',
|
|
451
|
+
'cdn.myapp.com'
|
|
452
|
+
],
|
|
453
|
+
|
|
454
|
+
// Debug configuration
|
|
455
|
+
debug: {
|
|
456
|
+
all: process.env.NODE_ENV === 'development',
|
|
457
|
+
routing: true,
|
|
458
|
+
auth: true
|
|
459
|
+
}
|
|
460
|
+
})
|
|
461
|
+
|
|
462
|
+
// Additional service registration
|
|
463
|
+
context.registerService(customWebService)
|
|
464
|
+
|
|
465
|
+
// Module registration with web-specific modules
|
|
466
|
+
context.registerModules([
|
|
467
|
+
...appModules,
|
|
468
|
+
...webSpecificModules
|
|
469
|
+
])
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### Integration with Internationalization
|
|
473
|
+
|
|
474
|
+
```typescript
|
|
475
|
+
import { makeContext } from '@owlmeans/web-client'
|
|
476
|
+
import { addI18nApp } from '@owlmeans/i18n'
|
|
477
|
+
|
|
478
|
+
// Add web-specific translations
|
|
479
|
+
addI18nApp('en', 'web-common', {
|
|
480
|
+
'button.close': 'Close',
|
|
481
|
+
'message.loading': 'Loading...',
|
|
482
|
+
'error.network': 'Network error occurred'
|
|
483
|
+
})
|
|
484
|
+
|
|
485
|
+
const context = makeContext(config)
|
|
486
|
+
|
|
487
|
+
// Access i18n through context
|
|
488
|
+
function I18nComponent() {
|
|
489
|
+
const context = useContext()
|
|
490
|
+
const i18nService = context.service('i18n')
|
|
491
|
+
|
|
492
|
+
return (
|
|
493
|
+
<div>
|
|
494
|
+
<button>{i18nService.t('button.close')}</button>
|
|
495
|
+
</div>
|
|
496
|
+
)
|
|
497
|
+
}
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
## Browser Compatibility
|
|
501
|
+
|
|
502
|
+
The package is designed for modern web browsers with support for:
|
|
503
|
+
|
|
504
|
+
- **ES2020+**: Modern JavaScript features
|
|
505
|
+
- **IndexedDB**: For local database storage
|
|
506
|
+
- **LocalStorage**: For simple key-value storage
|
|
507
|
+
- **DOM API**: Standard DOM manipulation
|
|
508
|
+
- **Fetch API**: For HTTP requests
|
|
509
|
+
- **WebCrypto**: For cryptographic operations (if used)
|
|
510
|
+
|
|
511
|
+
## Performance Optimizations
|
|
512
|
+
|
|
513
|
+
1. **Lazy Loading**: Components and services are loaded on demand
|
|
514
|
+
2. **Efficient Rendering**: Optimized ReactDOM integration
|
|
515
|
+
3. **Database Caching**: Intelligent caching of web database operations
|
|
516
|
+
4. **Bundle Splitting**: Designed for code splitting compatibility
|
|
517
|
+
5. **SSR Ready**: Full server-side rendering support
|
|
518
|
+
|
|
519
|
+
## Error Handling
|
|
520
|
+
|
|
521
|
+
Web-specific error handling and reporting:
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
import { OwlMeansError } from '@owlmeans/error'
|
|
525
|
+
|
|
526
|
+
// Web-specific error boundary
|
|
527
|
+
class WebErrorBoundary extends React.Component {
|
|
528
|
+
componentDidCatch(error, errorInfo) {
|
|
529
|
+
const context = this.props.context
|
|
530
|
+
const debugService = context.debug()
|
|
531
|
+
|
|
532
|
+
// Log web-specific error details
|
|
533
|
+
debugService.error('web-error', 'Browser error', {
|
|
534
|
+
error: error.message,
|
|
535
|
+
stack: error.stack,
|
|
536
|
+
userAgent: navigator.userAgent,
|
|
537
|
+
url: window.location.href
|
|
538
|
+
})
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
## Security Considerations
|
|
544
|
+
|
|
545
|
+
1. **Trusted Hosts**: Configure trusted hosts to prevent CSRF attacks
|
|
546
|
+
2. **Authentication Storage**: Secure token storage in browser
|
|
547
|
+
3. **XSS Protection**: Built-in protection against cross-site scripting
|
|
548
|
+
4. **Content Security Policy**: Compatible with CSP headers
|
|
549
|
+
5. **HTTPS Only**: Designed for secure HTTPS environments
|
|
550
|
+
|
|
551
|
+
## Integration with Other Packages
|
|
552
|
+
|
|
553
|
+
### Client Ecosystem Integration
|
|
554
|
+
```typescript
|
|
555
|
+
// Authentication
|
|
556
|
+
import { makeAuthService } from '@owlmeans/client-auth'
|
|
557
|
+
|
|
558
|
+
// Resources
|
|
559
|
+
import { makeResourceService } from '@owlmeans/client-resource'
|
|
560
|
+
|
|
561
|
+
// Internationalization
|
|
562
|
+
import { makeI18nService } from '@owlmeans/client-i18n'
|
|
563
|
+
|
|
564
|
+
// Database
|
|
565
|
+
import { WebDbService } from '@owlmeans/web-db'
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### Build Tool Integration
|
|
569
|
+
```typescript
|
|
570
|
+
// Webpack configuration
|
|
571
|
+
module.exports = {
|
|
572
|
+
resolve: {
|
|
573
|
+
alias: {
|
|
574
|
+
'@owlmeans/web-client': path.resolve(__dirname, 'node_modules/@owlmeans/web-client')
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Vite configuration
|
|
580
|
+
export default {
|
|
581
|
+
resolve: {
|
|
582
|
+
alias: {
|
|
583
|
+
'@owlmeans/web-client': path.resolve(__dirname, 'node_modules/@owlmeans/web-client')
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
## Best Practices
|
|
590
|
+
|
|
591
|
+
1. **Single Context**: Use one web context per application
|
|
592
|
+
2. **Proper Hydration**: Use hydration mode for SSR applications
|
|
593
|
+
3. **Error Boundaries**: Implement web-specific error boundaries
|
|
594
|
+
4. **Performance Monitoring**: Monitor web-specific performance metrics
|
|
595
|
+
5. **Responsive Design**: Ensure proper responsive behavior
|
|
596
|
+
6. **Accessibility**: Follow web accessibility guidelines
|
|
597
|
+
7. **SEO Optimization**: Use SSR for better search engine optimization
|
|
598
|
+
|
|
599
|
+
## Dependencies
|
|
600
|
+
|
|
601
|
+
This package depends on:
|
|
602
|
+
- `@owlmeans/client` - Base React client library
|
|
603
|
+
- `@owlmeans/client-context` - Client context management
|
|
604
|
+
- `@owlmeans/client-auth` - Client authentication
|
|
605
|
+
- `@owlmeans/web-db` - Web database integration
|
|
606
|
+
- `@owlmeans/client-i18n` - Client internationalization
|
|
607
|
+
- `react` - React library (peer dependency)
|
|
608
|
+
- `react-dom` - ReactDOM library (peer dependency)
|
|
609
|
+
- `react-router-dom` - React Router DOM (peer dependency)
|
|
610
|
+
|
|
611
|
+
## Related Packages
|
|
612
|
+
|
|
613
|
+
- [`@owlmeans/client`](../client) - Base React client library
|
|
614
|
+
- [`@owlmeans/native-client`](../native-client) - React Native implementation
|
|
615
|
+
- [`@owlmeans/web-db`](../web-db) - Web database implementation
|
|
616
|
+
- [`@owlmeans/client-auth`](../client-auth) - Client authentication
|
|
617
|
+
- [`@owlmeans/client-i18n`](../client-i18n) - Client internationalization
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":"AAOA,eAAO,MAAM,UAAU,6FAmCrB,CAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { DispatcherHOC } from '@owlmeans/client-auth';
|
|
3
|
+
import { useEffect } from 'react';
|
|
4
|
+
import { useSearchParams } from 'react-router-dom';
|
|
5
|
+
import { useI18nLib } from '@owlmeans/client-i18n';
|
|
6
|
+
import { AUTH_QUERY } from '@owlmeans/auth';
|
|
7
|
+
import { useContext } from '../../context.js';
|
|
8
|
+
export const Dispatcher = DispatcherHOC(({ provideToken }) => {
|
|
9
|
+
const [query] = useSearchParams();
|
|
10
|
+
const context = useContext();
|
|
11
|
+
const t = useI18nLib('auth', 'dispatcher');
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const token = query.get(AUTH_QUERY);
|
|
14
|
+
if (token != null) {
|
|
15
|
+
const params = {};
|
|
16
|
+
query.forEach((value, key) => {
|
|
17
|
+
if (key !== AUTH_QUERY) {
|
|
18
|
+
params[key] = value;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
provideToken({ token }, params);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
context.auth().authenticated().then(authzToken => {
|
|
25
|
+
if (authzToken == null) {
|
|
26
|
+
provideToken({ token: '' }, undefined);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}, []);
|
|
31
|
+
return query.has(AUTH_QUERY) ? _jsx("div", { style: {
|
|
32
|
+
width: '100%', // Makes the div occupy the full width
|
|
33
|
+
display: 'flex', // Enables flexbox layout
|
|
34
|
+
justifyContent: 'center', // Centers content horizontally
|
|
35
|
+
alignItems: 'center', // Centers content vertically (if needed)
|
|
36
|
+
textAlign: 'center', // Centers text within the div
|
|
37
|
+
paddingTop: '1rem', // Adds some vertical padding
|
|
38
|
+
paddingBottom: '1rem', // Adds some vertical padding
|
|
39
|
+
}, children: t('loading') }) : undefined;
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE;IAC3D,MAAM,CAAC,KAAK,CAAC,GAAG,eAAe,EAAE,CAAA;IACjC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAE5B,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAE1C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QACnC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,MAAM,MAAM,GAA2B,EAAE,CAAA;YACzC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC3B,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;oBACvB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;gBACrB,CAAC;YACH,CAAC,CAAC,CAAA;YAEF,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,CAAC,CAAA;QACjC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,EAAE,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;gBAC/C,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;oBACvB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,CAAC,CAAA;gBACxC,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,cAAK,KAAK,EAAE;YACzC,KAAK,EAAE,MAAM,EAAE,sCAAsC;YACrD,OAAO,EAAE,MAAM,EAAE,yBAAyB;YAC1C,cAAc,EAAE,QAAQ,EAAE,+BAA+B;YACzD,UAAU,EAAE,QAAQ,EAAE,yCAAyC;YAC/D,SAAS,EAAE,QAAQ,EAAE,8BAA8B;YACnD,UAAU,EAAE,MAAM,EAAE,6BAA6B;YACjD,aAAa,EAAE,MAAM,EAAE,6BAA6B;SACrD,YAAG,CAAC,CAAC,SAAS,CAAC,GAAO,CAAC,CAAC,CAAC,SAAS,CAAA;AACrC,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/dispatcher/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAA"}
|