@supersoniks/concorde 4.7.4 → 4.8.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/README.md +1 -1
- package/ai/cursor/rules/concorde.mdc +1 -1
- package/ai/skills/concorde-scope/SKILL.md +2 -2
- package/build-infos.json +1 -1
- package/concorde-core.bundle.js +289 -289
- package/concorde-core.es.js +4837 -4544
- package/dist/concorde-core.bundle.js +289 -289
- package/dist/concorde-core.es.js +4837 -4544
- package/dist/docs-mock-api-sw.js +19 -0
- package/dist/docs-mock-api-sw.js.map +2 -2
- package/docs/assets/index-wyNMyWT9.js +11196 -0
- package/docs/docs-mock-api-sw.js +19 -0
- package/docs/docs-mock-api-sw.js.map +2 -2
- package/docs/index.html +1 -1
- package/package.json +9 -1
- package/public/docs-mock-api-sw.js +19 -0
- package/public/docs-mock-api-sw.js.map +2 -2
- package/src/core/components/functional/example/example.ts +3 -3
- package/src/core/components/ui/icon/icon.ts +17 -2
- package/src/core/components/ui/menu/menu.ts +12 -3
- package/src/core/decorators/api.post.spec.ts +293 -0
- package/src/core/decorators/api.spec.ts +6 -6
- package/src/core/decorators/api.ts +643 -12
- package/src/core/decorators/subscriber/bind.ts +13 -5
- package/src/core/decorators/subscriber/dynamicPath.spec.ts +53 -0
- package/src/core/decorators/subscriber/dynamicPath.ts +23 -1
- package/src/core/decorators/subscriber/handle.ts +3 -1
- package/src/core/decorators/subscriber/onAssign.ts +10 -2
- package/src/core/decorators/subscriber/publish.ts +12 -2
- package/src/core/utils/PublisherProxy.ts +95 -11
- package/src/core/utils/api.ts +72 -3
- package/src/core/utils/dpOptions.spec.ts +56 -0
- package/src/core/utils/endpoint.ts +3 -3
- package/src/decorators.ts +17 -1
- package/src/docs/_core-concept/dataFlow.md +9 -3
- package/src/docs/_decorators/bind.md +2 -2
- package/src/docs/_decorators/get.md +13 -4
- package/src/docs/_decorators/handle.md +5 -1
- package/src/docs/_decorators/on-assign.md +2 -0
- package/src/docs/_decorators/patch.md +45 -0
- package/src/docs/_decorators/post.md +93 -0
- package/src/docs/_decorators/publish.md +1 -1
- package/src/docs/_decorators/put.md +43 -0
- package/src/docs/_decorators/subscribe.md +4 -1
- package/src/docs/_directives/sub.md +1 -1
- package/src/docs/_getting-started/my-first-component.md +1 -1
- package/src/docs/_misc/api-configuration.md +3 -1
- package/src/docs/_misc/dataProviderKey.md +2 -2
- package/src/docs/_misc/dynamic-path.md +71 -0
- package/src/docs/_misc/endpoint.md +5 -3
- package/src/docs/components/docs-demo-sources.ts +102 -3
- package/src/docs/components/docs-lit-demo-raw.ts +2 -26
- package/src/docs/components/docs-lit-demo.ts +9 -42
- package/src/docs/components/docs-source-excerpt.ts +53 -0
- package/src/docs/components/docs-source-link.ts +24 -8
- package/src/docs/components/docs-source-raw.ts +34 -0
- package/src/docs/example/decorators-demo-geo.ts +2 -2
- package/src/docs/example/decorators-demo-post.ts +249 -0
- package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +5 -5
- package/src/docs/example/decorators-demo.ts +1 -0
- package/src/docs/example/docs-api-config-demos.ts +5 -5
- package/src/docs/mock-api/router.ts +20 -0
- package/src/docs/navigation/navigation.ts +16 -0
- package/src/docs/search/docs-search.json +540 -15
- package/src/tsconfig.json +24 -0
- package/src/tsconfig.tsbuildinfo +1 -1
- package/vite.config.mts +1 -1
- package/docs/assets/index-CwtPzTFq.js +0 -7508
- package/docs/src/core/components/functional/date/date.md +0 -290
- package/docs/src/core/components/functional/fetch/fetch.md +0 -125
- package/docs/src/core/components/functional/if/if.md +0 -9
- package/docs/src/core/components/functional/list/list.md +0 -65
- package/docs/src/core/components/functional/mix/mix.md +0 -41
- package/docs/src/core/components/functional/queue/queue.md +0 -72
- package/docs/src/core/components/functional/router/router.md +0 -94
- package/docs/src/core/components/functional/sdui/default-library.json +0 -108
- package/docs/src/core/components/functional/sdui/example.json +0 -99
- package/docs/src/core/components/functional/sdui/sdui.md +0 -356
- package/docs/src/core/components/functional/states/states.md +0 -87
- package/docs/src/core/components/functional/submit/submit.md +0 -114
- package/docs/src/core/components/functional/subscriber/subscriber.md +0 -91
- package/docs/src/core/components/functional/value/value.md +0 -35
- package/docs/src/core/components/ui/alert/alert.md +0 -121
- package/docs/src/core/components/ui/alert-messages/alert-messages.md +0 -0
- package/docs/src/core/components/ui/badge/badge.md +0 -127
- package/docs/src/core/components/ui/button/button.md +0 -182
- package/docs/src/core/components/ui/captcha/captcha.md +0 -12
- package/docs/src/core/components/ui/card/card.md +0 -97
- package/docs/src/core/components/ui/divider/divider.md +0 -35
- package/docs/src/core/components/ui/form/checkbox/checkbox.md +0 -77
- package/docs/src/core/components/ui/form/fieldset/fieldset.md +0 -129
- package/docs/src/core/components/ui/form/form-actions/form-actions.md +0 -77
- package/docs/src/core/components/ui/form/form-layout/form-layout.md +0 -44
- package/docs/src/core/components/ui/form/input/input.md +0 -142
- package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -133
- package/docs/src/core/components/ui/form/radio/radio.md +0 -57
- package/docs/src/core/components/ui/form/select/select.md +0 -71
- package/docs/src/core/components/ui/form/switch/switch.md +0 -57
- package/docs/src/core/components/ui/form/textarea/textarea.md +0 -65
- package/docs/src/core/components/ui/group/group.md +0 -75
- package/docs/src/core/components/ui/icon/icon.md +0 -125
- package/docs/src/core/components/ui/icon/icons.json +0 -1
- package/docs/src/core/components/ui/image/image.md +0 -107
- package/docs/src/core/components/ui/link/link.md +0 -43
- package/docs/src/core/components/ui/loader/loader.md +0 -55
- package/docs/src/core/components/ui/menu/menu.md +0 -329
- package/docs/src/core/components/ui/modal/modal.md +0 -119
- package/docs/src/core/components/ui/pop/pop.md +0 -96
- package/docs/src/core/components/ui/progress/progress.md +0 -63
- package/docs/src/core/components/ui/table/table.md +0 -455
- package/docs/src/core/components/ui/toast/toast.md +0 -166
- package/docs/src/core/components/ui/tooltip/tooltip.md +0 -82
- package/docs/src/docs/_core-concept/dataFlow.md +0 -73
- package/docs/src/docs/_core-concept/overview.md +0 -57
- package/docs/src/docs/_core-concept/subscriber.md +0 -75
- package/docs/src/docs/_decorators/ancestor-attribute.md +0 -79
- package/docs/src/docs/_decorators/auto-subscribe.md +0 -202
- package/docs/src/docs/_decorators/bind.md +0 -167
- package/docs/src/docs/_decorators/get.md +0 -68
- package/docs/src/docs/_decorators/handle.md +0 -171
- package/docs/src/docs/_decorators/on-assign.md +0 -388
- package/docs/src/docs/_decorators/publish.md +0 -55
- package/docs/src/docs/_decorators/subscribe.md +0 -97
- package/docs/src/docs/_decorators/wait-for-ancestors.md +0 -163
- package/docs/src/docs/_directives/sub.md +0 -91
- package/docs/src/docs/_getting-started/ai-agents.md +0 -56
- package/docs/src/docs/_getting-started/concorde-manual-install.md +0 -133
- package/docs/src/docs/_getting-started/concorde-outside.md +0 -33
- package/docs/src/docs/_getting-started/create-a-component.md +0 -139
- package/docs/src/docs/_getting-started/my-first-component.md +0 -236
- package/docs/src/docs/_getting-started/my-first-subscriber.md +0 -120
- package/docs/src/docs/_getting-started/pubsub.md +0 -37
- package/docs/src/docs/_getting-started/start.md +0 -47
- package/docs/src/docs/_getting-started/theming.md +0 -91
- package/docs/src/docs/_misc/api-configuration.md +0 -79
- package/docs/src/docs/_misc/dataProviderKey.md +0 -168
- package/docs/src/docs/_misc/docs-mock-api.md +0 -60
- package/docs/src/docs/_misc/endpoint.md +0 -43
- package/docs/src/docs/_misc/html-integration.md +0 -13
- package/docs/src/docs/search/docs-search.json +0 -8532
- package/docs/src/tag-list.json +0 -1
- package/docs/src/tsconfig-model.json +0 -23
- package/docs/src/tsconfig.json +0 -1095
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
# @get
|
|
2
2
|
|
|
3
|
-
Loads data through [`API.getDetailed`](../../core/utils/api.ts). The decorated property is **`
|
|
3
|
+
Loads data through [`API.getDetailed`](../../core/utils/api.ts). The decorated property is **`ApiResult<T> | null`**: `request`, `response` (or `null` for `dataProvider(...)` resolution without HTTP), and typed `result`.
|
|
4
4
|
|
|
5
|
-
Pass an [`Endpoint<T>`](#docs/_misc/endpoint.md/endpoint) as the first argument. Import `get` and `
|
|
5
|
+
Pass an [`Endpoint<T>`](#docs/_misc/endpoint.md/endpoint) as the first argument. Import `get` and `ApiResult` from `@supersoniks/concorde/decorators`, and `Endpoint` from `@supersoniks/concorde/utils/endpoint`.
|
|
6
6
|
|
|
7
7
|
## Configuration
|
|
8
8
|
|
|
9
9
|
- **Default:** `HTML.getApiConfiguration(host)` (ancestor `serviceURL`, etc.).
|
|
10
10
|
- **Second argument:** `DataProviderKey<APIConfiguration>` — config is read from the publisher at the resolved path; internal mutations trigger another GET. See [API configuration](#docs/_misc/api-configuration.md/api-configuration) for mock demos.
|
|
11
11
|
|
|
12
|
+
## Dynamic path
|
|
13
|
+
|
|
14
|
+
`${prop}` on the endpoint or config key is resolved on the host. While a placeholder is `null` or `undefined`, no GET runs. Optional `skipEmptyPlaceholder: true` also blocks `""` (empty string only). Details: [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path).
|
|
15
|
+
|
|
12
16
|
## When the GET runs again
|
|
13
17
|
|
|
14
18
|
- A referenced Lit property changes (endpoint path and/or config key contains `${...}`).
|
|
@@ -18,7 +22,7 @@ Pass an [`Endpoint<T>`](#docs/_misc/endpoint.md/endpoint) as the first argument.
|
|
|
18
22
|
|
|
19
23
|
<sonic-code language="typescript">
|
|
20
24
|
<template>
|
|
21
|
-
import { get, type
|
|
25
|
+
import { get, type ApiResult } from "@supersoniks/concorde/decorators";
|
|
22
26
|
import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
|
|
23
27
|
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
24
28
|
</template>
|
|
@@ -32,7 +36,7 @@ Same demo service as [`sonic-queue`](../../core/components/functional/queue/queu
|
|
|
32
36
|
<template>
|
|
33
37
|
@get(new Endpoint<User>("users/${userId}"))
|
|
34
38
|
@state()
|
|
35
|
-
payload:
|
|
39
|
+
payload: ApiResult<User> | null = null;
|
|
36
40
|
</template>
|
|
37
41
|
</sonic-code>
|
|
38
42
|
|
|
@@ -66,3 +70,8 @@ Scoped `@get` with `@publish` / `@subscribe` on the payload (see [@publish](#doc
|
|
|
66
70
|
</sonic-code>
|
|
67
71
|
|
|
68
72
|
Stale responses are ignored if the path or generation changed before the request finished.
|
|
73
|
+
|
|
74
|
+
## See also
|
|
75
|
+
|
|
76
|
+
- [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path)
|
|
77
|
+
- [@post](#docs/_decorators/post.md/post) · [@put](#docs/_decorators/put.md/put) · [@patch](#docs/_decorators/patch.md/patch) — send decorators (same path rules)
|
|
@@ -161,6 +161,10 @@ onProfile(profile: Profile) {
|
|
|
161
161
|
|
|
162
162
|
> Options can be combined, e.g. `@handle(a, b, { waitForAllDefined: true, skip: [Skip.Nullish] })`. For any **arbitrary** validation on a specific value, just guard inside the method (`if (!isValid(v)) return;`) — that is exactly what an `accept`-style predicate would do, since `@handle` only runs your method.
|
|
163
163
|
|
|
164
|
+
### `skipEmptyPlaceholder`
|
|
165
|
+
|
|
166
|
+
On a **dynamic key path** (`"items.${itemId}"`), if `true`, a placeholder resolved to `''` is treated as not ready (no subscription) — **empty string only**, not `0` or `false`. See [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path).
|
|
167
|
+
|
|
164
168
|
## Highlights
|
|
165
169
|
|
|
166
170
|
- Strict typing: the method receives one argument per key, in order.
|
|
@@ -168,4 +172,4 @@ onProfile(profile: Profile) {
|
|
|
168
172
|
- By default the method runs on **every** assignment, even with `null` / `undefined` (unlike `@onAssign`, which waits for all values). Opt back into that behavior with `waitForAllDefined`.
|
|
169
173
|
- `skip` filters out values by **named category** (e.g. `[Skip.Nullish, Skip.EmptyObject]`); for arbitrary checks on a specific value, guard inside the method.
|
|
170
174
|
|
|
171
|
-
See also [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey).
|
|
175
|
+
See also [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey) and [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path).
|
|
@@ -128,6 +128,8 @@ Each placeholder is replaced at runtime with the current value of the correspond
|
|
|
128
128
|
- removes the previous subscriptions before attaching the new ones,
|
|
129
129
|
- observe the changes inside `willUpdate(changedProperties)` so nothing touches the getters/setters.
|
|
130
130
|
|
|
131
|
+
While a placeholder is `null`/`undefined`, subscriptions are detached. Optional `skipEmptyPlaceholder` on [@handle](#docs/_decorators/handle.md/handle) (typed replacement). Details: [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path).
|
|
132
|
+
|
|
131
133
|
|
|
132
134
|
<sonic-code language="typescript">
|
|
133
135
|
<template>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# @patch
|
|
2
|
+
|
|
3
|
+
Sends data through [`API.patchDetailed`](../../core/utils/api.ts). Same model as [@post](#docs/_decorators/post.md/post): decorated property is **`ApiResult<T> | null`** (`request`, `response`, `result`).
|
|
4
|
+
|
|
5
|
+
Pass an [`Endpoint<T>`](#docs/_misc/endpoint.md/endpoint) and a `DataProviderKey` for the **request body**. Import `patch` and `ApiResult` from `@supersoniks/concorde/decorators`.
|
|
6
|
+
|
|
7
|
+
## Configuration
|
|
8
|
+
|
|
9
|
+
Same as [@post](#docs/_decorators/post.md/post) / [@get](#docs/_decorators/get.md/get): scoped `HTML.getApiConfiguration(host)` or `DataProviderKey<APIConfiguration>` as third argument.
|
|
10
|
+
|
|
11
|
+
## Options (`PatchOptions`)
|
|
12
|
+
|
|
13
|
+
Same shape as `PostOptions` on [@post](#docs/_decorators/post.md/post) (`ApiSendOptions`): `refetchEveryMs`, `skipIfBodyMissing`, `autoPostOnBodyMutation`, `triggerKey`, `skipEmptyPlaceholder`. See [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path) for `${sessionId}` and empty-string behaviour.
|
|
14
|
+
|
|
15
|
+
## Import
|
|
16
|
+
|
|
17
|
+
<sonic-code language="typescript">
|
|
18
|
+
<template>
|
|
19
|
+
import { patch, type ApiResult } from "@supersoniks/concorde/decorators";
|
|
20
|
+
import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
|
|
21
|
+
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
22
|
+
</template>
|
|
23
|
+
</sonic-code>
|
|
24
|
+
|
|
25
|
+
## Example
|
|
26
|
+
|
|
27
|
+
<sonic-code language="typescript">
|
|
28
|
+
<template>
|
|
29
|
+
const patchBodyKey = new DataProviderKey<Partial<Resource>>("resourcePatch");
|
|
30
|
+
|
|
31
|
+
@patch(
|
|
32
|
+
new Endpoint<Resource, { resourceId: string }>("resources/${resourceId}"),
|
|
33
|
+
patchBodyKey,
|
|
34
|
+
{ skipEmptyPlaceholder: true },
|
|
35
|
+
)
|
|
36
|
+
@state()
|
|
37
|
+
payload?: ApiResult<Resource> | null;
|
|
38
|
+
</template>
|
|
39
|
+
</sonic-code>
|
|
40
|
+
|
|
41
|
+
## See also
|
|
42
|
+
|
|
43
|
+
- [@post](#docs/_decorators/post.md/post) — POST (live demos)
|
|
44
|
+
- [@put](#docs/_decorators/put.md/put) — full replacement (PUT)
|
|
45
|
+
- [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# @post
|
|
2
|
+
|
|
3
|
+
Sends data through [`API.postDetailed`](../../core/utils/api.ts). The decorated property is **`ApiResult<T> | null`**: `request`, `response`, and typed `result`.
|
|
4
|
+
|
|
5
|
+
Pass an [`Endpoint<T>`](#docs/_misc/endpoint.md/endpoint) as the first argument and a `DataProviderKey` for the **request body** as the second. Import `post` and `ApiResult` from `@supersoniks/concorde/decorators`, and `Endpoint` from `@supersoniks/concorde/utils/endpoint`.
|
|
6
|
+
|
|
7
|
+
## Configuration
|
|
8
|
+
|
|
9
|
+
Same as [@get](#docs/_decorators/get.md/get): scoped `HTML.getApiConfiguration(host)` by default, or `DataProviderKey<APIConfiguration>` as third argument. See [API configuration](#docs/_misc/api-configuration.md/api-configuration) for mock demos.
|
|
10
|
+
|
|
11
|
+
## Optional `PostOptions` (third or fourth argument)
|
|
12
|
+
|
|
13
|
+
| Option | Description |
|
|
14
|
+
|--------|-------------|
|
|
15
|
+
| `refetchEveryMs` | Re-post on an interval (ms). |
|
|
16
|
+
| `skipIfBodyMissing` | Skip when body publisher is `null`/`undefined` (default: `true`). |
|
|
17
|
+
| `autoPostOnBodyMutation` | Re-post when the body publisher mutates (default: `true`). `false` = manual via `triggerKey.invalidate()`. |
|
|
18
|
+
| `skipEmptyPlaceholder` | If `true`, a placeholder resolved to `''` blocks the request (empty string only — not `0` or `false`). See [Dynamic paths](#docs/_misc/dynamic-path.md/dynamic-path). |
|
|
19
|
+
| `triggerKey` | `DataProviderKey` — `invalidate()` re-runs the POST with the current body. |
|
|
20
|
+
|
|
21
|
+
## When the POST runs again
|
|
22
|
+
|
|
23
|
+
- Body publisher `onInternalMutation` when `autoPostOnBodyMutation` is `true` (default). Plusieurs mutations synchrones dans la même frame sont regroupées en **un seul POST** via `requestAnimationFrame`.
|
|
24
|
+
- Endpoint path dependency changes (`${sessionId}` on the host).
|
|
25
|
+
- Configuration publisher mutation.
|
|
26
|
+
- `triggerKey` publisher `invalidate()`.
|
|
27
|
+
- `refetchEveryMs` timer (if set).
|
|
28
|
+
|
|
29
|
+
## Import
|
|
30
|
+
|
|
31
|
+
<sonic-code language="typescript">
|
|
32
|
+
<template>
|
|
33
|
+
import { post, publish, type ApiResult } from "@supersoniks/concorde/decorators";
|
|
34
|
+
import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
|
|
35
|
+
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
36
|
+
</template>
|
|
37
|
+
</sonic-code>
|
|
38
|
+
|
|
39
|
+
## Minimal example
|
|
40
|
+
|
|
41
|
+
Mock service: `POST /docs-mock-api/api/register` (same route as [`sonic-submit`](#core/components/functional/submit/submit.md/submit) demos). Publisher setup lives in `decorators-demo-post.ts`.
|
|
42
|
+
|
|
43
|
+
<sonic-code language="typescript">
|
|
44
|
+
<template>
|
|
45
|
+
const syncRequest = new DataProviderKey<SyncRequest>("syncRequest");
|
|
46
|
+
const syncTrigger = new DataProviderKey<number>("syncTrigger");
|
|
47
|
+
|
|
48
|
+
@post(
|
|
49
|
+
new Endpoint<SyncResponse, { sessionId: string }>("sessions/${sessionId}/sync"),
|
|
50
|
+
syncRequest,
|
|
51
|
+
{ triggerKey: syncTrigger },
|
|
52
|
+
)
|
|
53
|
+
@state()
|
|
54
|
+
payload?: ApiResult<SyncResponse> | null;
|
|
55
|
+
</template>
|
|
56
|
+
</sonic-code>
|
|
57
|
+
|
|
58
|
+
## Live demos
|
|
59
|
+
|
|
60
|
+
<sonic-code>
|
|
61
|
+
<template>
|
|
62
|
+
<docs-demo-sources for="demo-api-post"></docs-demo-sources>
|
|
63
|
+
<demo-api-post></demo-api-post>
|
|
64
|
+
</template>
|
|
65
|
+
</sonic-code>
|
|
66
|
+
|
|
67
|
+
Dynamic endpoint path — changing `sessionId` on the host re-runs the POST (`POST /docs-mock-api/api/sessions/{id}/sync`):
|
|
68
|
+
|
|
69
|
+
<sonic-code>
|
|
70
|
+
<template>
|
|
71
|
+
<docs-demo-sources for="demo-api-post-dynamic"></docs-demo-sources>
|
|
72
|
+
<demo-api-post-dynamic></demo-api-post-dynamic>
|
|
73
|
+
</template>
|
|
74
|
+
</sonic-code>
|
|
75
|
+
|
|
76
|
+
`@post` + `@publish` on the same property (see [@publish](#docs/_decorators/publish.md/publish)):
|
|
77
|
+
|
|
78
|
+
<sonic-code>
|
|
79
|
+
<template>
|
|
80
|
+
<docs-demo-sources for="demo-api-post-publish"></docs-demo-sources>
|
|
81
|
+
<demo-api-post-publish></demo-api-post-publish>
|
|
82
|
+
</template>
|
|
83
|
+
</sonic-code>
|
|
84
|
+
|
|
85
|
+
Stale responses are ignored if the path or generation changed before the request finished.
|
|
86
|
+
|
|
87
|
+
**Note:** plusieurs composants `@post` sur la même page qui partagent le même `bodyKey` enverront chacun une requête à chaque mutation du body — utiliser une clé par composant (voir les deux démos live ci-dessus).
|
|
88
|
+
|
|
89
|
+
Path placeholders (`${sessionId}`, …): [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path).
|
|
90
|
+
|
|
91
|
+
## See also
|
|
92
|
+
|
|
93
|
+
- [@put](#docs/_decorators/put.md/put) · [@patch](#docs/_decorators/patch.md/patch) — same decorator model, `PUT` / `PATCH` via `putDetailed` / `patchDetailed`
|
|
@@ -52,4 +52,4 @@ export class DemoPublish extends LitElement {
|
|
|
52
52
|
</template>
|
|
53
53
|
</sonic-code>
|
|
54
54
|
|
|
55
|
-
Dynamic paths use the same placeholder rules as `@bind` / `@subscribe`.
|
|
55
|
+
Dynamic paths use the same placeholder rules as `@bind` / `@subscribe`. Resolution and `skipEmptyPlaceholder`: [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path).
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @put
|
|
2
|
+
|
|
3
|
+
Sends data through [`API.putDetailed`](../../core/utils/api.ts). Same model as [@post](#docs/_decorators/post.md/post): decorated property is **`ApiResult<T> | null`** (`request`, `response`, `result`).
|
|
4
|
+
|
|
5
|
+
Pass an [`Endpoint<T>`](#docs/_misc/endpoint.md/endpoint) and a `DataProviderKey` for the **request body**. Import `put` and `ApiResult` from `@supersoniks/concorde/decorators`.
|
|
6
|
+
|
|
7
|
+
## Configuration
|
|
8
|
+
|
|
9
|
+
Same as [@post](#docs/_decorators/post.md/post) / [@get](#docs/_decorators/get.md/get): scoped `HTML.getApiConfiguration(host)` or `DataProviderKey<APIConfiguration>` as third argument.
|
|
10
|
+
|
|
11
|
+
## Options (`PutOptions`)
|
|
12
|
+
|
|
13
|
+
Same shape as `PostOptions` on [@post](#docs/_decorators/post.md/post) (`ApiSendOptions`): `refetchEveryMs`, `skipIfBodyMissing`, `autoPostOnBodyMutation`, `triggerKey`, `skipEmptyPlaceholder`. See [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path) for `${sessionId}` and empty-string behaviour.
|
|
14
|
+
|
|
15
|
+
## Import
|
|
16
|
+
|
|
17
|
+
<sonic-code language="typescript">
|
|
18
|
+
<template>
|
|
19
|
+
import { put, type ApiResult } from "@supersoniks/concorde/decorators";
|
|
20
|
+
import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
|
|
21
|
+
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
22
|
+
</template>
|
|
23
|
+
</sonic-code>
|
|
24
|
+
|
|
25
|
+
## Example
|
|
26
|
+
|
|
27
|
+
<sonic-code language="typescript">
|
|
28
|
+
<template>
|
|
29
|
+
const bodyKey = new DataProviderKey<UpdatePayload>("resourceBody");
|
|
30
|
+
|
|
31
|
+
@put(new Endpoint<Resource, { resourceId: string }>("resources/${resourceId}"), bodyKey)
|
|
32
|
+
@state()
|
|
33
|
+
payload?: ApiResult<Resource> | null;
|
|
34
|
+
</template>
|
|
35
|
+
</sonic-code>
|
|
36
|
+
|
|
37
|
+
Changing `resourceId` on the host re-runs the PUT when the path becomes ready — see [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path).
|
|
38
|
+
|
|
39
|
+
## See also
|
|
40
|
+
|
|
41
|
+
- [@post](#docs/_decorators/post.md/post) — POST (live demos, polling, `@publish`)
|
|
42
|
+
- [@patch](#docs/_decorators/patch.md/patch) — partial update (PATCH)
|
|
43
|
+
- [Endpoint](#docs/_misc/endpoint.md/endpoint) · [API configuration](#docs/_misc/api-configuration.md/api-configuration)
|
|
@@ -45,7 +45,9 @@ cart: { items: string[] } | null = null;
|
|
|
45
45
|
|
|
46
46
|
## Dynamic path and scope
|
|
47
47
|
|
|
48
|
-
Placeholders `${prop}` in the key string are resolved from **properties on the same component**.
|
|
48
|
+
Placeholders `${prop}` in the key string are resolved from **properties on the same component**. While a value is `null`/`undefined`, the subscription is inactive; optional `{ skipEmptyPlaceholder: true }` also waits on `""`. Full rules: [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path).
|
|
49
|
+
|
|
50
|
+
Declare dynamic props in the key’s second generic so TypeScript expects them on the host:
|
|
49
51
|
|
|
50
52
|
<sonic-code language="typescript">
|
|
51
53
|
<template>
|
|
@@ -94,4 +96,5 @@ user: User | null = null;
|
|
|
94
96
|
|
|
95
97
|
- [Data flow](#docs/_core-concept/dataFlow.md/dataFlow) — overview
|
|
96
98
|
- [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey) — paths and host generics
|
|
99
|
+
- [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path) — `${prop}` resolution and `skipEmptyPlaceholder`
|
|
97
100
|
- [sub()](#docs/_directives/sub.md/sub) — same paths inside `html` templates
|
|
@@ -37,7 +37,7 @@ render() {
|
|
|
37
37
|
|
|
38
38
|
## Dynamic DataProviderKey (`${prop}`)
|
|
39
39
|
|
|
40
|
-
Like `@subscribe`: the path is resolved on the template **host component**; the directive re-subscribes when observed props change.
|
|
40
|
+
Like `@subscribe`: the path is resolved on the template **host component**; the directive re-subscribes when observed props change. Placeholder values (`null`, `""`, `0`, …): [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path) (`skipEmptyPlaceholder` not available on `sub()` yet).
|
|
41
41
|
|
|
42
42
|
<sonic-code language="typescript">
|
|
43
43
|
<template>
|
|
@@ -81,7 +81,7 @@ export const docsUserRowKey = new DataProviderKey<
|
|
|
81
81
|
</template>
|
|
82
82
|
</sonic-code>
|
|
83
83
|
|
|
84
|
-
The second generic (`{ dataProvider: string | null }`) lists what the host must expose so `"${dataProvider}"` can be resolved. See [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey).
|
|
84
|
+
The second generic (`{ dataProvider: string | null }`) lists what the host must expose so `"${dataProvider}"` can be resolved. See [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey) and [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path).
|
|
85
85
|
|
|
86
86
|
### Scope — which store segment applies
|
|
87
87
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# API configuration
|
|
2
2
|
|
|
3
|
-
`APIConfiguration` is the object built by [`HTML.getApiConfiguration`](../../core/utils/HTML.ts) from **ancestor attributes** on the DOM (or from a typed publisher — see [@get
|
|
3
|
+
`APIConfiguration` is the object built by [`HTML.getApiConfiguration`](../../core/utils/HTML.ts) from **ancestor attributes** on the DOM (or from a typed publisher — see [@get](#docs/_decorators/get.md/get) / [@post](#docs/_decorators/post.md/post) configuration key). It is passed to [`API`](../../core/utils/api.ts) by fetchers, **sonic-submit**, the **`wording()`** directive, **`@get`**, **`@post`**, **`@put`**, and **`@patch`**.
|
|
4
4
|
|
|
5
5
|
> **Mock service:** same [Local API demos](#docs/_misc/docs-mock-api.md/docs-mock-api) Service Worker / Vite middleware. Routes used on this page are listed in the [API config routes](#api-config-routes) section below.
|
|
6
6
|
|
|
@@ -74,6 +74,8 @@ Implementation: `src/docs/mock-api/api-config-mock.ts` (bundled in the Service W
|
|
|
74
74
|
## See also
|
|
75
75
|
|
|
76
76
|
- [@get](#docs/_decorators/get.md/get) — `APIConfiguration` + `Endpoint`
|
|
77
|
+
- [@post](#docs/_decorators/post.md/post) — same configuration model for POST
|
|
78
|
+
- [@put](#docs/_decorators/put.md/put) · [@patch](#docs/_decorators/patch.md/patch) — PUT / PATCH
|
|
77
79
|
- [Endpoint](#docs/_misc/endpoint.md/endpoint) — typed path
|
|
78
80
|
- [Local API demos](#docs/_misc/docs-mock-api.md/docs-mock-api) — offline `serviceURL`
|
|
79
81
|
- [Fetch](#core/components/functional/fetch/fetch.md/fetch) — attribute table (legacy sonic-fetch)
|
|
@@ -78,7 +78,7 @@ firstItem.path; // "data.items.0"
|
|
|
78
78
|
|
|
79
79
|
### Dynamic paths
|
|
80
80
|
|
|
81
|
-
Use placeholders `${prop}` or `{$prop}` in the path string. The path is resolved at runtime from the component's properties. The type remains declarative:
|
|
81
|
+
Use placeholders `${prop}` or `{$prop}` in the path string. The path is resolved at runtime from the component's properties. See [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path) for resolution rules and `skipEmptyPlaceholder`. The type remains declarative:
|
|
82
82
|
|
|
83
83
|
<sonic-code language="typescript">
|
|
84
84
|
<template>
|
|
@@ -159,7 +159,7 @@ export class UserForm extends LitElement {
|
|
|
159
159
|
</template>
|
|
160
160
|
</sonic-code>
|
|
161
161
|
|
|
162
|
-
These decorators support dynamic paths: `"base.${prop}"` in the constructor. A wrong property type (e.g. `number` for `DataProviderKey<string>`) is a TypeScript error. See [@handle](#docs/_decorators/handle.md/handle) for method callbacks.
|
|
162
|
+
These decorators support dynamic paths: `"base.${prop}"` in the constructor. A wrong property type (e.g. `number` for `DataProviderKey<string>`) is a TypeScript error. Resolution rules: [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path). See [@handle](#docs/_decorators/handle.md/handle) for method callbacks.
|
|
163
163
|
|
|
164
164
|
## Notes
|
|
165
165
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Dynamic path placeholders
|
|
2
|
+
|
|
3
|
+
Decorators and `DataProviderKey` paths can include **placeholders** resolved on the host component at runtime:
|
|
4
|
+
|
|
5
|
+
- `${prop}` or `{$prop}` — e.g. `"users/${userId}"`, `"api/sessions/${sessionId}/sync"`
|
|
6
|
+
- Nested expressions — e.g. `"teams.${teamId}.members"`
|
|
7
|
+
|
|
8
|
+
Resolution is done by [`resolveDynamicPath`](../../core/decorators/subscriber/dynamicPath.ts). The root property names (`userId`, `sessionId`, …) are watched via `requestAnimationFrame` (see `dynamicPropertyWatch.ts`).
|
|
9
|
+
|
|
10
|
+
## Default behaviour (`ready` / `not ready`)
|
|
11
|
+
|
|
12
|
+
| Placeholder value | Path `ready`? | Inserted segment | Notes |
|
|
13
|
+
|-------------------|---------------|------------------|-------|
|
|
14
|
+
| `undefined` | **no** | — | Wait until defined |
|
|
15
|
+
| `null` | **no** | — | Same as undefined |
|
|
16
|
+
| `""` | **yes** | empty string | e.g. `sessions//sync` — request may still run |
|
|
17
|
+
| `0` | **yes** | `"0"` | Not treated as “missing” |
|
|
18
|
+
| `false` | **yes** | `"false"` | |
|
|
19
|
+
| `42`, `"alpha"` | **yes** | `"42"`, `"alpha"` | |
|
|
20
|
+
|
|
21
|
+
When `ready: false`, decorators **do not** call the network (for `@get` / `@post` / `@put` / `@patch`), **unsubscribe** (`@bind` / `@subscribe`), or skip publisher binding (`@publish` / `@handle`). The decorated property is often left unchanged or set to `undefined` (HTTP decorators).
|
|
22
|
+
|
|
23
|
+
When the placeholder later becomes valid, observers run again and behaviour resumes.
|
|
24
|
+
|
|
25
|
+
## `skipEmptyPlaceholder` option
|
|
26
|
+
|
|
27
|
+
Some APIs should not run while an id is still `""`. Opt in per decorator:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
@get(new Endpoint<User, { userId: string }>("users/${userId}"), {
|
|
31
|
+
skipEmptyPlaceholder: true,
|
|
32
|
+
})
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
| Option | Scope |
|
|
36
|
+
|--------|--------|
|
|
37
|
+
| `skipEmptyPlaceholder?: boolean` | **Only** empty string `''` on a placeholder |
|
|
38
|
+
| Default `false` | `""` is inserted into the path (legacy behaviour) |
|
|
39
|
+
| `true` | `""` → `ready: false`, same as `null` / `undefined` for that segment |
|
|
40
|
+
|
|
41
|
+
Does **not** affect `0`, `false`, `null`, or `undefined` (nullish stays “not ready” regardless).
|
|
42
|
+
|
|
43
|
+
Available on:
|
|
44
|
+
|
|
45
|
+
| API | Where |
|
|
46
|
+
|-----|--------|
|
|
47
|
+
| `@get` | 2nd or 3rd argument (`GetOptions`) |
|
|
48
|
+
| `@post` / `@put` / `@patch` | `PostOptions` / `ApiSendOptions` |
|
|
49
|
+
| `@bind` / `@subscribe` | `BindOptions` |
|
|
50
|
+
| `@publish` | 2nd argument `PublishOptions` |
|
|
51
|
+
| `@handle` | `HandleOptions` |
|
|
52
|
+
|
|
53
|
+
## Per-decorator summary
|
|
54
|
+
|
|
55
|
+
| Decorator | `ready: false` | `ready: true` |
|
|
56
|
+
|-----------|----------------|---------------|
|
|
57
|
+
| `@get` | No HTTP; `payload` → `undefined` | `ApiResult` assigned |
|
|
58
|
+
| `@post` / `@put` / `@patch` | No HTTP; `payload` → `undefined` | `ApiResult` assigned |
|
|
59
|
+
| `@subscribe` / `@bind` | Unsubscribe; prop keeps last value | Subscribe `onAssign` |
|
|
60
|
+
| `@publish` | Internal publisher `null`; writes ignored | `publisher.set` on assign |
|
|
61
|
+
| `@handle` | No subscription; with `waitForAllDefined`, method not called | Callback on assign |
|
|
62
|
+
|
|
63
|
+
## See also
|
|
64
|
+
|
|
65
|
+
- [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey) — path syntax
|
|
66
|
+
- [Endpoint](#docs/_misc/endpoint.md/endpoint) — HTTP paths + host generic `U`
|
|
67
|
+
- HTTP: [@get](#docs/_decorators/get.md/get) · [@post](#docs/_decorators/post.md/post) · [@put](#docs/_decorators/put.md/put) · [@patch](#docs/_decorators/patch.md/patch)
|
|
68
|
+
- Store: [@subscribe](#docs/_decorators/subscribe.md/subscribe) · [@bind](#docs/_decorators/bind.md/bind) · [@publish](#docs/_decorators/publish.md/publish) · [@handle](#docs/_decorators/handle.md/handle)
|
|
69
|
+
- Legacy strings: [@onAssign](#docs/_decorators/on-assign.md/on-assign) (dynamic paths section)
|
|
70
|
+
- Templates: [sub()](#docs/_directives/sub.md/sub) — dynamic paths in Lit (no `skipEmptyPlaceholder` yet)
|
|
71
|
+
- Tutorial: [My first component](#docs/_getting-started/my-first-component.md/my-first-component) — `"${dataProvider}"` scope pattern
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`Endpoint<T, U>` describes a single HTTP path (or a path accepted by `API.get`) and carries the expected response type `T`. Unlike [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey), there is no dot-navigation: the path is one string.
|
|
4
4
|
|
|
5
|
-
The optional second generic `U` (default `any`) describes host properties used to resolve dynamic segments in the path (`${…}` / `{$…}`), for example with
|
|
5
|
+
The optional second generic `U` (default `any`) describes host properties used to resolve dynamic segments in the path (`${…}` / `{$…}`), for example with [@get](#docs/_decorators/get.md/get) or [@post](#docs/_decorators/post.md/post). See [Dynamic path placeholders](#docs/_misc/dynamic-path.md/dynamic-path) for `null` / `undefined` / `""` / `0` and `skipEmptyPlaceholder`.
|
|
6
6
|
|
|
7
7
|
## Import
|
|
8
8
|
|
|
@@ -30,7 +30,7 @@ const one = new Endpoint<User, { userId: string }>("users/${userId}");
|
|
|
30
30
|
|
|
31
31
|
## Publisher key for payloads
|
|
32
32
|
|
|
33
|
-
`getDataProviderKey()` returns a typed publisher key whose `path` matches the endpoint path (payload typing follows `
|
|
33
|
+
`getDataProviderKey()` returns a typed publisher key whose `path` matches the endpoint path (payload typing follows `ApiResult` for this endpoint). Useful when pairing `@get` with `@publish` / `@subscribe` (see [@get](#docs/_decorators/get.md/get)).
|
|
34
34
|
|
|
35
35
|
## Data-provider paths
|
|
36
36
|
|
|
@@ -39,5 +39,7 @@ const one = new Endpoint<User, { userId: string }>("users/${userId}");
|
|
|
39
39
|
## See also
|
|
40
40
|
|
|
41
41
|
- [API configuration](#docs/_misc/api-configuration.md/api-configuration) — `serviceURL`, token, wording (mock demos)
|
|
42
|
-
- [@get](#docs/_decorators/get.md/get) — decorator
|
|
42
|
+
- [@get](#docs/_decorators/get.md/get) — GET decorator
|
|
43
|
+
- [@post](#docs/_decorators/post.md/post) — POST decorator (body from a `DataProviderKey`)
|
|
44
|
+
- [@put](#docs/_decorators/put.md/put) · [@patch](#docs/_decorators/patch.md/patch) — PUT / PATCH decorators
|
|
43
45
|
- [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey) — typed publisher paths (dot notation)
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import { html, LitElement, nothing } from "lit";
|
|
2
|
-
import { customElement, property } from "lit/decorators.js";
|
|
1
|
+
import { css, html, LitElement, nothing } from "lit";
|
|
2
|
+
import { customElement, property, state } from "lit/decorators.js";
|
|
3
|
+
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
4
|
+
import { tailwind } from "../tailwind";
|
|
3
5
|
import { docsSourceLinks, type DocsSource } from "./docs-source-link";
|
|
6
|
+
import { DOCS_SOURCE_RAW } from "./docs-source-raw";
|
|
7
|
+
import { resolveSourceExcerpt } from "./docs-source-excerpt";
|
|
8
|
+
import "../prism/prism";
|
|
9
|
+
import { prismCSS } from "../prism";
|
|
10
|
+
import * as Prism from "prismjs";
|
|
11
|
+
import "prismjs/components/prism-typescript";
|
|
4
12
|
|
|
5
13
|
export type { DocsSource };
|
|
6
14
|
|
|
@@ -260,6 +268,30 @@ export const DOCS_DEMO_SOURCE_REGISTRY: Record<string, DocsSource[]> = {
|
|
|
260
268
|
},
|
|
261
269
|
{ path: "src/docs/example/decorators-demo-geo.ts", label: "geo API" },
|
|
262
270
|
],
|
|
271
|
+
"demo-api-post": [
|
|
272
|
+
{
|
|
273
|
+
path: "src/docs/example/decorators-demo-post.ts",
|
|
274
|
+
line: 53,
|
|
275
|
+
label: "demo-api-post",
|
|
276
|
+
},
|
|
277
|
+
{ path: "src/docs/mock-api/router.ts", label: "mock router" },
|
|
278
|
+
],
|
|
279
|
+
"demo-api-post-dynamic": [
|
|
280
|
+
{
|
|
281
|
+
path: "src/docs/example/decorators-demo-post.ts",
|
|
282
|
+
line: 143,
|
|
283
|
+
label: "demo-api-post-dynamic",
|
|
284
|
+
},
|
|
285
|
+
{ path: "src/docs/mock-api/router.ts", label: "mock router (sessions sync)" },
|
|
286
|
+
],
|
|
287
|
+
"demo-api-post-publish": [
|
|
288
|
+
{
|
|
289
|
+
path: "src/docs/example/decorators-demo-post.ts",
|
|
290
|
+
line: 209,
|
|
291
|
+
label: "demo-api-post-publish",
|
|
292
|
+
},
|
|
293
|
+
{ path: "src/docs/mock-api/router.ts", label: "mock router" },
|
|
294
|
+
],
|
|
263
295
|
"demo-handle": [
|
|
264
296
|
{
|
|
265
297
|
path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
|
|
@@ -384,14 +416,81 @@ export const DOCS_DEMO_SOURCE_REGISTRY: Record<string, DocsSource[]> = {
|
|
|
384
416
|
],
|
|
385
417
|
};
|
|
386
418
|
|
|
419
|
+
function highlightTs(code: string): string {
|
|
420
|
+
return Prism.highlight(code, Prism.languages.typescript, "typescript");
|
|
421
|
+
}
|
|
422
|
+
|
|
387
423
|
@customElement("docs-demo-sources")
|
|
388
424
|
export class DocsDemoSources extends LitElement {
|
|
425
|
+
static styles = [
|
|
426
|
+
tailwind,
|
|
427
|
+
prismCSS,
|
|
428
|
+
css`
|
|
429
|
+
:host {
|
|
430
|
+
display: block;
|
|
431
|
+
margin-bottom: 0.75rem;
|
|
432
|
+
}
|
|
433
|
+
pre {
|
|
434
|
+
font-size: 13px !important;
|
|
435
|
+
margin: 0;
|
|
436
|
+
}
|
|
437
|
+
`,
|
|
438
|
+
];
|
|
439
|
+
|
|
389
440
|
/** Registry key matching the live demo custom element tag. */
|
|
390
441
|
@property({ attribute: "for" }) forTag = "";
|
|
391
442
|
|
|
443
|
+
@property({ type: Boolean, attribute: "show-code" }) showCode = true;
|
|
444
|
+
|
|
445
|
+
@state() private highlighted = "";
|
|
446
|
+
|
|
447
|
+
connectedCallback() {
|
|
448
|
+
super.connectedCallback();
|
|
449
|
+
this.refreshHighlight();
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
updated(changed: Map<string, unknown>) {
|
|
453
|
+
super.updated(changed);
|
|
454
|
+
if (changed.has("forTag") || changed.has("showCode")) {
|
|
455
|
+
this.refreshHighlight();
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
private refreshHighlight() {
|
|
460
|
+
if (!this.showCode) {
|
|
461
|
+
this.highlighted = "";
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
const sources = DOCS_DEMO_SOURCE_REGISTRY[this.forTag];
|
|
465
|
+
const primary = sources?.[0];
|
|
466
|
+
if (!primary) {
|
|
467
|
+
this.highlighted = "";
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
const raw = DOCS_SOURCE_RAW[primary.path];
|
|
471
|
+
if (!raw) {
|
|
472
|
+
console.warn(`[docs-demo-sources] No raw source for ${primary.path}`);
|
|
473
|
+
this.highlighted = "";
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
const excerpt = resolveSourceExcerpt(raw, this.forTag, {
|
|
477
|
+
line: primary.line,
|
|
478
|
+
});
|
|
479
|
+
this.highlighted = highlightTs(excerpt);
|
|
480
|
+
}
|
|
481
|
+
|
|
392
482
|
render() {
|
|
393
483
|
const sources = DOCS_DEMO_SOURCE_REGISTRY[this.forTag];
|
|
394
484
|
if (!sources?.length) return nothing;
|
|
395
|
-
return
|
|
485
|
+
return html`
|
|
486
|
+
${docsSourceLinks(sources)}
|
|
487
|
+
${this.showCode && this.highlighted
|
|
488
|
+
? html`
|
|
489
|
+
<pre
|
|
490
|
+
class="rounded-md custom-scroll language-typescript overflow-auto border border-neutral-200/80 dark:border-neutral-700/80"
|
|
491
|
+
><code>${unsafeHTML(this.highlighted)}</code></pre>
|
|
492
|
+
`
|
|
493
|
+
: nothing}
|
|
494
|
+
`;
|
|
396
495
|
}
|
|
397
496
|
}
|
|
@@ -1,28 +1,4 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Included in the **docs** bundle (`src/docs.ts`), not in the **core** library build (`src/index.ts`).
|
|
4
|
-
* Add one import + map entry when registering a new file in `DOCS_LIT_DEMO_REGISTRY`.
|
|
2
|
+
* @deprecated Importez `DOCS_SOURCE_RAW` depuis `./docs-source-raw`.
|
|
5
3
|
*/
|
|
6
|
-
|
|
7
|
-
import docsListDemos from "../example/docs-list-demos.ts?raw";
|
|
8
|
-
import docsQueueDemos from "../example/docs-queue-demos.ts?raw";
|
|
9
|
-
import docsToggleDemos from "../example/docs-toggle-demos.ts?raw";
|
|
10
|
-
import docsUserTwoScopes from "../example/docs-user-two-scopes.ts?raw";
|
|
11
|
-
import docsRouterDemos from "../example/docs-router-demos.ts?raw";
|
|
12
|
-
import docsSubmitDemos from "../example/docs-submit-demos.ts?raw";
|
|
13
|
-
import docsApiConfigDemos from "../example/docs-api-config-demos.ts?raw";
|
|
14
|
-
import docsUsersList from "../example/docs-users-list.ts?raw";
|
|
15
|
-
import users from "../example/users.ts?raw";
|
|
16
|
-
|
|
17
|
-
export const DOCS_LIT_DEMO_RAW: Record<string, string> = {
|
|
18
|
-
"src/docs/example/docs-toggle-demos.ts": docsToggleDemos,
|
|
19
|
-
"src/docs/example/docs-joke-demos.ts": docsJokeDemos,
|
|
20
|
-
"src/docs/example/docs-queue-demos.ts": docsQueueDemos,
|
|
21
|
-
"src/docs/example/docs-list-demos.ts": docsListDemos,
|
|
22
|
-
"src/docs/example/docs-router-demos.ts": docsRouterDemos,
|
|
23
|
-
"src/docs/example/docs-submit-demos.ts": docsSubmitDemos,
|
|
24
|
-
"src/docs/example/docs-api-config-demos.ts": docsApiConfigDemos,
|
|
25
|
-
"src/docs/example/docs-users-list.ts": docsUsersList,
|
|
26
|
-
"src/docs/example/docs-user-two-scopes.ts": docsUserTwoScopes,
|
|
27
|
-
"src/docs/example/users.ts": users,
|
|
28
|
-
};
|
|
4
|
+
export { DOCS_LIT_DEMO_RAW, DOCS_SOURCE_RAW } from "./docs-source-raw";
|