@owlmeans/api-config-client 0.1.18-rc.46 → 0.1.18-rc.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,44 +1,111 @@
|
|
|
1
1
|
# @owlmeans/api-config-client
|
|
2
2
|
|
|
3
|
-
Client-side middleware that fetches server config from `GET /assets/config.json` and merges it into
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- `
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
Client-side middleware that fetches server config from `GET /assets/config.json` and merges it into
|
|
4
|
+
the client context. It is the browser half of the runtime config flow: `@owlmeans/api-config`
|
|
5
|
+
declares the `advertise` protocol and the public-field allowlist, `@owlmeans/api-config-server`
|
|
6
|
+
answers it, and this package binds and calls it during `init()`. An app built on
|
|
7
|
+
`@owlmeans/web-panel` or `@owlmeans/mui-panel` already has both halves wired and does not touch
|
|
8
|
+
this package; a client context built from a lower layer registers it itself. Config that is fixed at
|
|
9
|
+
build time needs no runtime fetch — use `@owlmeans/client-config` for that. The package's skill is
|
|
10
|
+
`api-config-client`.
|
|
10
11
|
|
|
11
12
|
## Installation
|
|
12
13
|
|
|
13
14
|
```bash
|
|
14
|
-
bun add @owlmeans/api-config-client@^0.1.18-rc.
|
|
15
|
+
bun add @owlmeans/api-config-client@^0.1.18-rc.47
|
|
15
16
|
```
|
|
16
17
|
|
|
18
|
+
The middleware imports `mergeConfig` from `@owlmeans/config`, which this package's manifest does not
|
|
19
|
+
declare; a standalone install adds `@owlmeans/config` to its own dependencies.
|
|
20
|
+
|
|
21
|
+
## Concepts
|
|
22
|
+
|
|
23
|
+
- **Advertise protocol** — `advertise` from `@owlmeans/api-config`, alias `API_CONFIG`
|
|
24
|
+
(`'api-config:advertise'`), an open sticky route at `/assets/config.json`.
|
|
25
|
+
- **Binding** — `entrypoints`, this package's `[bind(advertise)]`: the client entrypoint the
|
|
26
|
+
middleware resolves by alias.
|
|
27
|
+
- **Middleware** — `apiConfigMiddleware`, a `Context` / `Loading` middleware: it runs once during
|
|
28
|
+
`init()`, after every service and resource has initialized and before the context becomes ready.
|
|
29
|
+
- **Primary host** — `cfg.primaryHost` / `cfg.primaryPort`: where the config is fetched from. The
|
|
30
|
+
fetch happens only when `primaryHost` is set; `@owlmeans/web-client` fills both from
|
|
31
|
+
`window.location`.
|
|
32
|
+
- **Merge** — the answer is merged into `context.cfg` in place with `configHelper.mergeConfig`.
|
|
33
|
+
|
|
17
34
|
## Usage
|
|
18
35
|
|
|
19
|
-
|
|
36
|
+
### Wire both halves in a lower-layer client context
|
|
37
|
+
|
|
38
|
+
The middleware does the work; the binding is what it calls. Registering one without the other fails
|
|
39
|
+
the boot.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { makeClientContext } from '@owlmeans/client-context'
|
|
43
|
+
import { apiConfigMiddleware, entrypoints as apiConfigBindings } from '@owlmeans/api-config-client'
|
|
44
|
+
|
|
45
|
+
export const makeContext = <C extends AppConfig, T extends AppContext<C>>(cfg: C): T => {
|
|
46
|
+
const context = makeClientContext<C, T>(cfg)
|
|
47
|
+
context.registerMiddleware(apiConfigMiddleware)
|
|
48
|
+
|
|
49
|
+
return context
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const clientBindings = [...apiConfigBindings, ...myClientBindings]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Point the fetch at a backend
|
|
20
56
|
|
|
21
57
|
```typescript
|
|
22
|
-
|
|
58
|
+
const context = makeContext({
|
|
59
|
+
...config,
|
|
60
|
+
primaryHost: 'app.example.com',
|
|
61
|
+
primaryPort: 8443,
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
await context.configure().init() // fetches /assets/config.json from app.example.com:8443 and merges it
|
|
65
|
+
```
|
|
23
66
|
|
|
24
|
-
|
|
67
|
+
### Read merged values at render or request time
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
const brand = context.cfg.brand // the server's value once init() has resolved
|
|
25
71
|
```
|
|
26
72
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
fails rather than silently falling back to alias-based calls.
|
|
73
|
+
A service that copied a config value during its own `init()` keeps the bundled value — the merge
|
|
74
|
+
happens after service initialization.
|
|
30
75
|
|
|
31
76
|
## API
|
|
32
77
|
|
|
33
|
-
|
|
78
|
+
| Symbol | Kind | Purpose |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| `apiConfigMiddleware` | `Middleware` | `Context` / `Loading`; resolves `API_CONFIG`, sets the route's `host`/`port` from `cfg.primaryHost`/`cfg.primaryPort`, calls it and merges the `ApiConfig` answer into `context.cfg` |
|
|
81
|
+
| `entrypoints` | `ClientEntrypoint[]` | `[bind(advertise)]` — the browser-local binding of the shared runtime-config protocol |
|
|
82
|
+
|
|
83
|
+
### Merge behaviour
|
|
84
|
+
|
|
85
|
+
`configHelper.mergeConfig` merges objects key by key and appends arrays. A server value replaces the
|
|
86
|
+
bundled one only where the bundled value is a scalar, `null` or absent; a scalar sent for a bundled
|
|
87
|
+
object or array is dropped silently, and a bundled array grows on every merge.
|
|
88
|
+
|
|
89
|
+
## Common pitfalls
|
|
34
90
|
|
|
35
|
-
|
|
36
|
-
|
|
91
|
+
- Registering `apiConfigMiddleware` without the `entrypoints` bindings — `init()` throws
|
|
92
|
+
`SyntaxError: Entrypoint api-config:advertise not found` rather than silently falling back.
|
|
93
|
+
- No `cfg.primaryHost` — the middleware does nothing and the app runs on the bundled config.
|
|
94
|
+
- A failed fetch is logged (`API config not loaded`) and swallowed; an unreachable backend shows up
|
|
95
|
+
as missing values later, never as a boot error.
|
|
96
|
+
- Registering the pair again on a `web-panel` / `mui-panel` context — those factories already do it.
|
|
97
|
+
- Expecting the server to empty or replace a bundled array — the merge only appends.
|
|
98
|
+
- Only fields an `apiConfigPlugin` allows are advertised; a value missing on the client may simply
|
|
99
|
+
not be exposed by the server.
|
|
37
100
|
|
|
38
|
-
## Related
|
|
101
|
+
## Related packages
|
|
39
102
|
|
|
40
|
-
- [`@owlmeans/api-config`](../api-config) — `API_CONFIG`
|
|
103
|
+
- [`@owlmeans/api-config`](../api-config) — `API_CONFIG`, the `advertise` protocol, `ApiConfig` and the field allowlist
|
|
41
104
|
- [`@owlmeans/api-config-server`](../api-config-server) — server that serves the config endpoint
|
|
105
|
+
- [`@owlmeans/config`](../config) — `configHelper.mergeConfig`
|
|
106
|
+
- [`@owlmeans/client-entrypoint`](../client-entrypoint) — `bind`, the client entrypoint binding
|
|
107
|
+
- [`@owlmeans/client-context`](../client-context) — the client context and `primaryHost` / `primaryPort`
|
|
108
|
+
- [`@owlmeans/web-panel`](../web-panel) — a panel factory that already wires this package
|
|
42
109
|
|
|
43
110
|
<!-- owlmeans:agent-guidance:start -->
|
|
44
111
|
## Agent guidance
|
|
@@ -48,7 +115,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
48
115
|
your project's skill store (`.agents/skills/`):
|
|
49
116
|
|
|
50
117
|
```sh
|
|
51
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
118
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.52
|
|
52
119
|
```
|
|
53
120
|
|
|
54
121
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/api-config-client",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-10-
|
|
4
|
+
"version": "0.1.18-rc.47",
|
|
5
|
+
"generatedAt": "2026-10-08T21:27:54.305Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/api-config-client
|
|
9
9
|
|
|
10
10
|
**Layer:** Client
|
|
11
|
-
**Install:** `"@owlmeans/api-config-client": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/api-config-client": "^0.1.18-rc.47"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
Consumes the declaration shared by `@owlmeans/api-config` and answered by
|
|
14
14
|
`@owlmeans/api-config-server`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/api-config-client",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.47",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@owlmeans/api-config": "^0.1.18-rc.43",
|
|
25
|
-
"@owlmeans/client-context": "^0.1.18-rc.
|
|
26
|
-
"@owlmeans/client-entrypoint": "^0.1.18-rc.
|
|
25
|
+
"@owlmeans/client-context": "^0.1.18-rc.50",
|
|
26
|
+
"@owlmeans/client-entrypoint": "^0.1.18-rc.49",
|
|
27
27
|
"@owlmeans/context": "^0.1.18-rc.34",
|
|
28
|
-
"@owlmeans/log": "^0.1.18-rc.
|
|
28
|
+
"@owlmeans/log": "^0.1.18-rc.3"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@owlmeans/dep-config": "workspace:*",
|