@owlmeans/client-route 0.1.18-rc.9 → 0.1.18
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 +20 -16
- package/agent-meta/manifest.json +3 -3
- package/agent-meta/skills/client-route/SKILL.md +18 -7
- package/build/helper/types.d.ts +9 -0
- package/build/helper/types.d.ts.map +1 -0
- package/build/helper/types.js +2 -0
- package/build/helper/types.js.map +1 -0
- package/build/helper.d.ts +3 -3
- package/build/helper.d.ts.map +1 -1
- package/build/helper.js +9 -5
- package/build/helper.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js.map +1 -1
- package/build/model.d.ts +7 -2
- package/build/model.d.ts.map +1 -1
- package/build/model.js +8 -20
- package/build/model.js.map +1 -1
- package/build/types.d.ts +7 -5
- package/build/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/helper/types.ts +9 -0
- package/src/helper.ts +14 -7
- package/src/index.ts +1 -0
- package/src/model.ts +11 -33
- package/src/types.ts +7 -5
- package/build/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -4,33 +4,33 @@ Client-side route model extension — marks routes as client-side and provides U
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
- `route(routeModel, opts?)` — wraps a `
|
|
8
|
-
- `isClientRouteModel(route)` — type guard distinguishing client routes from server routes
|
|
9
|
-
- `extractParams(path)` — extracts path parameter names (`:param` segments) from a URL pattern
|
|
10
|
-
- Used internally by `@owlmeans/client-
|
|
7
|
+
- `route(routeModel, opts?)` — wraps a `RouteModel` into a `ClientRouteModel` (marks `_client: true`)
|
|
8
|
+
- `clientRouteHelper.isClientRouteModel(route)` — type guard distinguishing client routes from server routes
|
|
9
|
+
- `clientRouteHelper.extractParams(path)` — extracts path parameter names (`:param` segments) from a URL pattern
|
|
10
|
+
- Used internally by `@owlmeans/client-entrypoint` when building client-side entrypoint URLs
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
bun add @owlmeans/client-route
|
|
15
|
+
bun add @owlmeans/client-route@^0.1.18
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
20
20
|
```typescript
|
|
21
|
-
import { route,
|
|
21
|
+
import { route, clientRouteHelper } from '@owlmeans/client-route'
|
|
22
22
|
import type { ClientRouteModel } from '@owlmeans/client-route'
|
|
23
23
|
|
|
24
24
|
// Wrap a route as a client route
|
|
25
|
-
const clientRoute = route(someRouteModel, { overrides: {
|
|
25
|
+
const clientRoute = route(someRouteModel, { overrides: { service: 'api' } })
|
|
26
26
|
|
|
27
27
|
// Type guard
|
|
28
|
-
if (isClientRouteModel(arg)) {
|
|
28
|
+
if (clientRouteHelper.isClientRouteModel(arg)) {
|
|
29
29
|
// arg is ClientRouteModel
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
// Extract named params from a path pattern
|
|
33
|
-
const params = extractParams('/projects/:projectId/items/:itemId')
|
|
33
|
+
const params = clientRouteHelper.extractParams('/projects/:projectId/items/:itemId')
|
|
34
34
|
// => ['projectId', 'itemId']
|
|
35
35
|
```
|
|
36
36
|
|
|
@@ -38,24 +38,28 @@ const params = extractParams('/projects/:projectId/items/:itemId')
|
|
|
38
38
|
|
|
39
39
|
### `route(route, opts?): ClientRouteModel`
|
|
40
40
|
|
|
41
|
-
Converts a `
|
|
41
|
+
Converts a `RouteModel` to a `ClientRouteModel`. Options: `overrides?: Partial<ClientRoute>` — the
|
|
42
|
+
overrides only fill in declaration fields that are still unset.
|
|
42
43
|
|
|
43
|
-
### `isClientRouteModel(route): route is ClientRouteModel`
|
|
44
|
+
### `clientRouteHelper.isClientRouteModel(route): route is ClientRouteModel`
|
|
44
45
|
|
|
45
46
|
Returns `true` if the route was created with `route()`.
|
|
46
47
|
|
|
47
|
-
### `extractParams(path): string[]`
|
|
48
|
+
### `clientRouteHelper.extractParams(path): string[]`
|
|
48
49
|
|
|
49
50
|
Returns the list of `:param` segment names in a URL pattern string.
|
|
50
51
|
|
|
51
52
|
### `ClientRouteModel`
|
|
52
53
|
|
|
53
|
-
Extends `
|
|
54
|
+
Extends `RouteModel` with the `_client: true` flag. It holds no address state: the declaration keeps
|
|
55
|
+
only the segment this route contributes, and the entrypoint answers `segment()`, `path()`, `mount()`
|
|
56
|
+
and `address()` on demand against the context that asks.
|
|
54
57
|
|
|
55
58
|
## Related Packages
|
|
56
59
|
|
|
57
|
-
- [`@owlmeans/route`](../route) — `
|
|
58
|
-
|
|
60
|
+
- [`@owlmeans/route`](../route) — `RouteModel`, `RouteDeclaration` base types and the pure
|
|
61
|
+
`resolvePath` / `resolveMount` / `resolveAddress` utilities under `@owlmeans/route/utils`
|
|
62
|
+
- [`@owlmeans/client-entrypoint`](../client-entrypoint) — uses `route()` and `clientRouteHelper.isClientRouteModel()` when constructing entrypoints
|
|
59
63
|
|
|
60
64
|
<!-- owlmeans:agent-guidance:start -->
|
|
61
65
|
## Agent guidance
|
|
@@ -65,7 +69,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
65
69
|
your project's skill store (`.agents/skills/`):
|
|
66
70
|
|
|
67
71
|
```sh
|
|
68
|
-
npx @owlmeans/agent-skills
|
|
72
|
+
npx @owlmeans/agent-skills@^0.1.18
|
|
69
73
|
```
|
|
70
74
|
|
|
71
75
|
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
|
-
"schemaVersion":
|
|
2
|
+
"schemaVersion": 3,
|
|
3
3
|
"package": "@owlmeans/client-route",
|
|
4
|
-
"version": "0.1.18
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18",
|
|
5
|
+
"generatedAt": "2026-10-28T00:31:34.710Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: client-route
|
|
3
|
-
description: How to use @owlmeans/client-route —
|
|
3
|
+
description: How to use @owlmeans/client-route — marking a route model as client-side and extracting its :params. Auto-invoked when importing client route helpers.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
@@ -8,24 +8,35 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/client-route
|
|
9
9
|
|
|
10
10
|
**Layer:** Client
|
|
11
|
-
**Install:** `"@owlmeans/client-route": "^0.1.18
|
|
11
|
+
**Install:** `"@owlmeans/client-route": "^0.1.18"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
## Key Exports
|
|
14
14
|
|
|
15
15
|
| Export | Description |
|
|
16
16
|
|--------|-------------|
|
|
17
|
-
| `
|
|
18
|
-
|
|
|
19
|
-
|
|
|
17
|
+
| `route(model, opts?)` | Mark a route model as a client one, filling in whatever the declaration left blank |
|
|
18
|
+
| `ClientRouteModel` | A `RouteModel` carrying the `_client: true` marker |
|
|
19
|
+
| `ClientRoute` | The declaration a client route wraps |
|
|
20
|
+
| `ClientRouteOptions` | `{ overrides }` — defaults applied to blank declaration fields |
|
|
21
|
+
| `isClientRouteModel(obj)` | The `_client` marker test |
|
|
22
|
+
| `extractParams(path)` | The `:param` names a path declares, in order |
|
|
20
23
|
|
|
21
24
|
## Usage
|
|
22
25
|
|
|
23
26
|
Most app code uses route declarations from `@owlmeans/route` and lets `@owlmeans/web-router` consume them. Import here only for custom routing.
|
|
24
27
|
|
|
25
28
|
```typescript
|
|
26
|
-
import {
|
|
29
|
+
import { route, extractParams } from '@owlmeans/client-route'
|
|
30
|
+
|
|
31
|
+
const model = route(declaration, { overrides: { service: 'manager' } })
|
|
32
|
+
extractParams('/project/:id/task/:taskId') // ['id', 'taskId']
|
|
27
33
|
```
|
|
28
34
|
|
|
35
|
+
Marking is all this does: the declared `path` stays the **segment** the route contributes, and the
|
|
36
|
+
full path, mount and address are computed by the entrypoint against the context that asks. Nothing
|
|
37
|
+
here rewrites a declaration — `overrides` only fills fields the declaration left blank.
|
|
38
|
+
|
|
29
39
|
## Depends On
|
|
30
40
|
|
|
31
|
-
- `@owlmeans/route`,
|
|
41
|
+
- `@owlmeans/route` — `RouteModel`, `overrideParams` (from `/utils`), `normalizePath`, `SEP`, `PARAM`
|
|
42
|
+
- `@owlmeans/client-context`
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ClientRouteModel } from '../types.js';
|
|
2
|
+
/** Reads client route models and their paths. */
|
|
3
|
+
export interface ClientRouteHelper {
|
|
4
|
+
/** Whether a route model was marked as a client one. */
|
|
5
|
+
isClientRouteModel: (route: Object) => route is ClientRouteModel;
|
|
6
|
+
/** The names of the `:param` segments of a path, in order. */
|
|
7
|
+
extractParams: (path: string) => string[];
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/helper/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IAChC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,gBAAgB,CAAA;IAChE,8DAA8D;IAC9D,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;CAC1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/helper/types.ts"],"names":[],"mappings":""}
|
package/build/helper.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
1
|
+
import type { ClientRouteHelper } from './helper/types.js';
|
|
2
|
+
export declare const createClientRouteHelper: () => ClientRouteHelper;
|
|
3
|
+
export declare const clientRouteHelper: ClientRouteHelper;
|
|
4
4
|
//# sourceMappingURL=helper.d.ts.map
|
package/build/helper.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAE1D,eAAO,MAAM,uBAAuB,QAAO,iBAW1C,CAAA;AAED,eAAO,MAAM,iBAAiB,mBAA4B,CAAA"}
|
package/build/helper.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { PARAM, SEP, normalizePath } from '@owlmeans/route';
|
|
2
|
-
export const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
.
|
|
2
|
+
export const createClientRouteHelper = () => {
|
|
3
|
+
const isClientRouteModel = (route) => '_client' in route;
|
|
4
|
+
const extractParams = (path) => {
|
|
5
|
+
path = normalizePath(path);
|
|
6
|
+
return path.split(SEP).map(item => item.startsWith(PARAM) ? item.slice(1) : null)
|
|
7
|
+
.filter(param => param);
|
|
8
|
+
};
|
|
9
|
+
return { isClientRouteModel, extractParams };
|
|
7
10
|
};
|
|
11
|
+
export const clientRouteHelper = createClientRouteHelper();
|
|
8
12
|
//# sourceMappingURL=helper.js.map
|
package/build/helper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAI3D,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAsB,EAAE;IAC7D,MAAM,kBAAkB,GAAG,CAAC,KAAa,EAA6B,EAAE,CACtE,SAAS,IAAI,KAAK,CAAA;IAEpB,MAAM,aAAa,GAAG,CAAC,IAAY,EAAY,EAAE;QAC/C,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;aAC9E,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAa,CAAA;IACvC,CAAC,CAAA;IAED,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAA;AAC9C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,uBAAuB,EAAE,CAAA"}
|
package/build/index.d.ts
CHANGED
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,mBAAmB,YAAY,CAAA;AAC/B,mBAAmB,mBAAmB,CAAA;AACtC,cAAc,aAAa,CAAA"}
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAG1B,cAAc,aAAa,CAAA"}
|
package/build/model.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RouteModel } from '@owlmeans/route';
|
|
2
2
|
import type { ClientRouteModel, ClientRouteOptions } from './types.js';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Mark a route model as a client one and fill in whatever the declaration left blank.
|
|
5
|
+
* The declared `path` stays the segment this route contributes — the entrypoint composes the
|
|
6
|
+
* full path and the address on demand.
|
|
7
|
+
*/
|
|
8
|
+
export declare const route: (route: RouteModel, opts?: ClientRouteOptions) => ClientRouteModel;
|
|
4
9
|
//# sourceMappingURL=model.d.ts.map
|
package/build/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAGtE;;;;GAIG;AACH,eAAO,MAAM,KAAK,UAAW,UAAU,SAAS,kBAAkB,KAAG,gBAUpE,CAAA"}
|
package/build/model.js
CHANGED
|
@@ -1,27 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { routeDeclarationHelper } from '@owlmeans/route/utils';
|
|
2
|
+
/**
|
|
3
|
+
* Mark a route model as a client one and fill in whatever the declaration left blank.
|
|
4
|
+
* The declared `path` stays the segment this route contributes — the entrypoint composes the
|
|
5
|
+
* full path and the address on demand.
|
|
6
|
+
*/
|
|
2
7
|
export const route = (route, opts) => {
|
|
3
|
-
const unresolvedPath = route.route.path;
|
|
4
8
|
const model = {
|
|
5
9
|
...route,
|
|
6
|
-
_client: true
|
|
7
|
-
resolve: async (context) => {
|
|
8
|
-
if (model.route.resolved) {
|
|
9
|
-
if (model._resolved == null) {
|
|
10
|
-
throw new SyntaxError('Cannot reach resolved state twice without resolving promise');
|
|
11
|
-
}
|
|
12
|
-
await model._resolved;
|
|
13
|
-
return model.route;
|
|
14
|
-
}
|
|
15
|
-
const resolver = {};
|
|
16
|
-
model._resolved = new Promise(resolve => resolver.resolve = resolve);
|
|
17
|
-
await resolve(model.route)(context);
|
|
18
|
-
model.route.partialPath = unresolvedPath;
|
|
19
|
-
resolver.resolve?.();
|
|
20
|
-
return model.route;
|
|
21
|
-
}
|
|
10
|
+
_client: true
|
|
22
11
|
};
|
|
23
|
-
overrideParams(model.route, opts?.overrides);
|
|
24
|
-
model.route.partialPath = unresolvedPath;
|
|
12
|
+
routeDeclarationHelper.overrideParams(model.route, opts?.overrides);
|
|
25
13
|
return model;
|
|
26
14
|
};
|
|
27
15
|
//# sourceMappingURL=model.js.map
|
package/build/model.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAE9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAiB,EAAE,IAAyB,EAAoB,EAAE;IACtF,MAAM,KAAK,GAAqB;QAC9B,GAAI,KAA0B;QAE9B,OAAO,EAAE,IAAI;KACd,CAAA;IAED,sBAAsB,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;IAEnE,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
|
package/build/types.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export interface ClientRoute extends
|
|
3
|
-
partialPath: string;
|
|
1
|
+
import type { RouteDeclaration, RouteModel } from '@owlmeans/route';
|
|
2
|
+
export interface ClientRoute extends RouteDeclaration {
|
|
4
3
|
}
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* A route declaration marked as belonging to the client side. It carries no state of its own —
|
|
6
|
+
* the segment, path and address are computed by the entrypoint against the context that asks.
|
|
7
|
+
*/
|
|
8
|
+
export interface ClientRouteModel extends RouteModel {
|
|
6
9
|
route: ClientRoute;
|
|
7
|
-
_resolved?: Promise<void>;
|
|
8
10
|
_client: true;
|
|
9
11
|
}
|
|
10
12
|
export interface ClientRouteOptions {
|
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,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEnE,MAAM,WAAW,WAAY,SAAQ,gBAAgB;CACpD;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,KAAK,EAAE,WAAW,CAAA;IAClB,OAAO,EAAE,IAAI,CAAA;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;CACjC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/client-route",
|
|
3
|
-
"version": "0.1.18
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@owlmeans/client-context": "^0.1.18
|
|
25
|
-
"@owlmeans/route": "^0.1.18
|
|
24
|
+
"@owlmeans/client-context": "^0.1.18",
|
|
25
|
+
"@owlmeans/route": "^0.1.18"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@owlmeans/dep-config": "
|
|
28
|
+
"@owlmeans/dep-config": "^0.1.18",
|
|
29
29
|
"nodemon": "^3.1.14",
|
|
30
30
|
"typescript": "^7.0.2"
|
|
31
31
|
},
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ClientRouteModel } from '../types.js'
|
|
2
|
+
|
|
3
|
+
/** Reads client route models and their paths. */
|
|
4
|
+
export interface ClientRouteHelper {
|
|
5
|
+
/** Whether a route model was marked as a client one. */
|
|
6
|
+
isClientRouteModel: (route: Object) => route is ClientRouteModel
|
|
7
|
+
/** The names of the `:param` segments of a path, in order. */
|
|
8
|
+
extractParams: (path: string) => string[]
|
|
9
|
+
}
|
package/src/helper.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { PARAM, SEP, normalizePath } from '@owlmeans/route'
|
|
2
|
-
import { ClientRouteModel } from './types.js'
|
|
2
|
+
import type { ClientRouteModel } from './types.js'
|
|
3
|
+
import type { ClientRouteHelper } from './helper/types.js'
|
|
3
4
|
|
|
4
|
-
export const
|
|
5
|
-
|
|
5
|
+
export const createClientRouteHelper = (): ClientRouteHelper => {
|
|
6
|
+
const isClientRouteModel = (route: Object): route is ClientRouteModel =>
|
|
7
|
+
'_client' in route
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const extractParams = (path: string): string[] => {
|
|
10
|
+
path = normalizePath(path)
|
|
11
|
+
return path.split(SEP).map(item => item.startsWith(PARAM) ? item.slice(1) : null)
|
|
12
|
+
.filter(param => param) as string[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return { isClientRouteModel, extractParams }
|
|
11
16
|
}
|
|
17
|
+
|
|
18
|
+
export const clientRouteHelper = createClientRouteHelper()
|
package/src/index.ts
CHANGED
package/src/model.ts
CHANGED
|
@@ -1,42 +1,20 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RouteModel } from '@owlmeans/route'
|
|
2
2
|
import type { ClientRouteModel, ClientRouteOptions } from './types.js'
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import { routeDeclarationHelper } from '@owlmeans/route/utils'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Mark a route model as a client one and fill in whatever the declaration left blank.
|
|
7
|
+
* The declared `path` stays the segment this route contributes — the entrypoint composes the
|
|
8
|
+
* full path and the address on demand.
|
|
9
|
+
*/
|
|
10
|
+
export const route = (route: RouteModel, opts?: ClientRouteOptions): ClientRouteModel => {
|
|
9
11
|
const model: ClientRouteModel = {
|
|
10
12
|
...(route as ClientRouteModel),
|
|
11
13
|
|
|
12
|
-
_client: true
|
|
13
|
-
|
|
14
|
-
resolve: async <C>(context: C) => {
|
|
15
|
-
if (model.route.resolved) {
|
|
16
|
-
if (model._resolved == null) {
|
|
17
|
-
throw new SyntaxError('Cannot reach resolved state twice without resolving promise')
|
|
18
|
-
}
|
|
19
|
-
await model._resolved
|
|
20
|
-
|
|
21
|
-
return model.route
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const resolver: { resolve?: () => void } = {}
|
|
25
|
-
model._resolved = new Promise(resolve => resolver.resolve = resolve)
|
|
26
|
-
|
|
27
|
-
await resolve(model.route)(context as BasicContext<BasicConfig>)
|
|
28
|
-
|
|
29
|
-
model.route.partialPath = unresolvedPath
|
|
30
|
-
|
|
31
|
-
resolver.resolve?.()
|
|
32
|
-
|
|
33
|
-
return model.route
|
|
34
|
-
}
|
|
14
|
+
_client: true
|
|
35
15
|
}
|
|
36
16
|
|
|
37
|
-
overrideParams(model.route, opts?.overrides)
|
|
38
|
-
|
|
39
|
-
model.route.partialPath = unresolvedPath
|
|
17
|
+
routeDeclarationHelper.overrideParams(model.route, opts?.overrides)
|
|
40
18
|
|
|
41
19
|
return model
|
|
42
20
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RouteDeclaration, RouteModel } from '@owlmeans/route'
|
|
2
2
|
|
|
3
|
-
export interface ClientRoute extends
|
|
4
|
-
partialPath: string
|
|
3
|
+
export interface ClientRoute extends RouteDeclaration {
|
|
5
4
|
}
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* A route declaration marked as belonging to the client side. It carries no state of its own —
|
|
8
|
+
* the segment, path and address are computed by the entrypoint against the context that asks.
|
|
9
|
+
*/
|
|
10
|
+
export interface ClientRouteModel extends RouteModel {
|
|
8
11
|
route: ClientRoute
|
|
9
|
-
_resolved?: Promise<void>
|
|
10
12
|
_client: true
|
|
11
13
|
}
|
|
12
14
|
|
package/build/.gitkeep
DELETED
|
File without changes
|