@supersoniks/concorde 4.2.1 → 4.4.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 +163 -0
- package/build-infos.json +1 -1
- package/concorde-core.bundle.js +585 -670
- package/concorde-core.es.js +7165 -9505
- package/dist/concorde-core.bundle.js +585 -670
- package/dist/concorde-core.es.js +7165 -9505
- package/docs/assets/index-DP1oMukw.js +4949 -0
- package/docs/assets/index-DZtxIZCW.css +1 -0
- package/docs/index.html +2 -2
- package/{src/docs/_misc → docs/src/docs/_decorators}/ancestor-attribute.md +15 -31
- package/docs/src/docs/_decorators/bind.md +164 -0
- package/docs/src/docs/_decorators/get.md +65 -0
- package/docs/src/docs/_decorators/publish.md +54 -0
- package/docs/src/docs/_decorators/subscribe.md +36 -0
- package/docs/src/docs/_misc/dataProviderKey.md +135 -0
- package/docs/src/docs/_misc/endpoint.md +42 -0
- package/docs/src/docs/search/docs-search.json +850 -710
- package/docs/src/tsconfig.json +43 -4
- package/package.json +25 -4
- package/php/get-challenge.php +34 -0
- package/php/some-service.php +42 -0
- package/scripts/pre-build.mjs +4 -0
- package/src/core/_types/endpoint.ts +4 -0
- package/src/core/_types/key.ts +1 -0
- package/src/core/components/functional/example/example.ts +38 -6
- package/src/core/decorators/Subscriber.ts +2 -0
- package/src/core/decorators/api.spec.ts +150 -0
- package/src/core/decorators/api.ts +244 -0
- package/src/core/decorators/subscriber/bind.ts +57 -145
- package/src/core/decorators/subscriber/dynamicPath.ts +77 -0
- package/src/core/decorators/subscriber/dynamicPropertyWatch.ts +105 -0
- package/src/core/decorators/subscriber/onAssign.ts +11 -147
- package/src/core/decorators/subscriber/publish.spec.ts +21 -0
- package/src/core/decorators/subscriber/publish.ts +148 -0
- package/src/core/decorators/subscriber/publisherPath.ts +13 -0
- package/src/core/decorators/subscriber/subscribe.spec.ts +21 -0
- package/src/core/decorators/subscriber/subscribe.ts +32 -0
- package/src/core/decorators/subscriber/subscribe.type-test.ts +32 -0
- package/src/core/utils/api.ts +83 -15
- package/src/core/utils/dataProviderKey.spec.ts +34 -0
- package/src/core/utils/dataProviderKey.ts +86 -0
- package/src/core/utils/endpoint.spec.ts +41 -0
- package/src/core/utils/endpoint.ts +87 -0
- package/src/decorators.ts +14 -0
- package/{docs/src/docs/_misc → src/docs/_decorators}/ancestor-attribute.md +15 -31
- package/src/docs/_decorators/bind.md +164 -0
- package/src/docs/_decorators/get.md +65 -0
- package/src/docs/_decorators/publish.md +54 -0
- package/src/docs/_decorators/subscribe.md +36 -0
- package/src/docs/_misc/dataProviderKey.md +135 -0
- package/src/docs/_misc/endpoint.md +42 -0
- package/src/docs/example/decorators-demo-bind-demos.ts +210 -0
- package/src/docs/example/decorators-demo-geo.ts +45 -0
- package/src/docs/example/decorators-demo-init.ts +228 -0
- package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +324 -0
- package/src/docs/example/decorators-demo.ts +12 -459
- package/src/docs/navigation/navigation.ts +27 -10
- package/src/docs/search/docs-search.json +1059 -609
- package/src/tsconfig-model.json +1 -1
- package/src/tsconfig.json +65 -1
- package/src/tsconfig.tsbuildinfo +1 -1
- package/src/utils.ts +8 -1
- package/vite/config.js +25 -6
- package/vite.config.mts +13 -0
- package/docs/assets/index-B0IJ9I_B.js +0 -4918
- package/docs/assets/index-B3QHEJTV.css +0 -1
- package/docs/src/docs/_misc/bind.md +0 -436
- package/docs/src/docs/_misc/key.md +0 -135
- package/src/docs/_misc/bind.md +0 -362
- /package/docs/src/docs/{_misc → _decorators}/auto-subscribe.md +0 -0
- /package/docs/src/docs/{_misc → _decorators}/on-assign.md +0 -0
- /package/docs/src/docs/{_misc → _decorators}/wait-for-ancestors.md +0 -0
- /package/src/docs/{_misc → _decorators}/auto-subscribe.md +0 -0
- /package/src/docs/{_misc → _decorators}/on-assign.md +0 -0
- /package/src/docs/{_misc → _decorators}/wait-for-ancestors.md +0 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# DataProviderKey
|
|
2
|
+
|
|
3
|
+
The `DataProviderKey<T>` utility provides type-safe navigation through composite data structures. Each property or index access extends the path, and the final key can be retrieved via `toString()` or the `path` property.
|
|
4
|
+
|
|
5
|
+
For a **single HTTP path string** (no dot-syntax), see [Endpoint](#docs/_misc/endpoint.md/endpoint).
|
|
6
|
+
|
|
7
|
+
## Principle
|
|
8
|
+
|
|
9
|
+
`DataProviderKey` uses a Proxy to intercept property access and build a cumulative path string. TypeScript infers the nested type at each level, so `myKey.items[0]` is correctly typed as `DataProviderKey<Item>` when `items` is `Item[]`.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Import
|
|
14
|
+
|
|
15
|
+
<sonic-code language="typescript">
|
|
16
|
+
<template>
|
|
17
|
+
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
18
|
+
</template>
|
|
19
|
+
</sonic-code>
|
|
20
|
+
|
|
21
|
+
### Basic example
|
|
22
|
+
|
|
23
|
+
<sonic-code language="typescript">
|
|
24
|
+
<template>
|
|
25
|
+
type Item = { id: string; name: string };
|
|
26
|
+
//
|
|
27
|
+
type Data = {
|
|
28
|
+
items: Item[];
|
|
29
|
+
count: number;
|
|
30
|
+
};
|
|
31
|
+
//
|
|
32
|
+
const myKey = new DataProviderKey<Data>("data").items[0];
|
|
33
|
+
// Equivalent to: new DataProviderKey<Item>("data.items.0")
|
|
34
|
+
myKey.toString(); // "data.items.0"
|
|
35
|
+
myKey.path; // same value
|
|
36
|
+
// myKey is typed as DataProviderKey<Item>
|
|
37
|
+
</template>
|
|
38
|
+
</sonic-code>
|
|
39
|
+
|
|
40
|
+
### Object property access
|
|
41
|
+
|
|
42
|
+
<sonic-code language="typescript">
|
|
43
|
+
<template>
|
|
44
|
+
const key = new DataProviderKey<Data>("data");
|
|
45
|
+
const countKey = key.count;
|
|
46
|
+
countKey.path; // "data.count"
|
|
47
|
+
countKey.toString(); // "data.count"
|
|
48
|
+
</template>
|
|
49
|
+
</sonic-code>
|
|
50
|
+
|
|
51
|
+
### Array index access
|
|
52
|
+
|
|
53
|
+
<sonic-code language="typescript">
|
|
54
|
+
<template>
|
|
55
|
+
const itemsKey = new DataProviderKey<Data>("data").items;
|
|
56
|
+
itemsKey.path; // "data.items"
|
|
57
|
+
// itemsKey is DataProviderKey<Item[]>
|
|
58
|
+
//
|
|
59
|
+
const firstItem = itemsKey[0];
|
|
60
|
+
firstItem.path; // "data.items.0"
|
|
61
|
+
// firstItem is DataProviderKey<Item>
|
|
62
|
+
</template>
|
|
63
|
+
</sonic-code>
|
|
64
|
+
|
|
65
|
+
### Dynamic paths
|
|
66
|
+
|
|
67
|
+
Use placeholders `${prop}` or `{$prop}` in the path string. The path is resolved at runtime from the component's properties. The type remains declarative:
|
|
68
|
+
|
|
69
|
+
<sonic-code language="typescript">
|
|
70
|
+
<template>
|
|
71
|
+
type User = { name: string; email: string };
|
|
72
|
+
//
|
|
73
|
+
// Path resolved from component.userIndex at runtime
|
|
74
|
+
@subscribe(new DataProviderKey<User>("users.${userIndex}"))
|
|
75
|
+
@state()
|
|
76
|
+
user: User | null = null;
|
|
77
|
+
</template>
|
|
78
|
+
</sonic-code>
|
|
79
|
+
|
|
80
|
+
## Path retrieval
|
|
81
|
+
|
|
82
|
+
The final path is built by concatenating each accessed property with a dot:
|
|
83
|
+
|
|
84
|
+
- `new DataProviderKey<T>("base")` → `"base"`
|
|
85
|
+
- `key.prop` → `"base.prop"`
|
|
86
|
+
- `key.items[0]` → `"base.items.0"`
|
|
87
|
+
|
|
88
|
+
Use `toString()` or `path` to get the full path string:
|
|
89
|
+
|
|
90
|
+
<sonic-code language="typescript">
|
|
91
|
+
<template>
|
|
92
|
+
const key = new DataProviderKey<Data>("data").count;
|
|
93
|
+
const pathString = key.toString(); // "data.count"
|
|
94
|
+
const pathProp = key.path; // "data.count"
|
|
95
|
+
</template>
|
|
96
|
+
</sonic-code>
|
|
97
|
+
|
|
98
|
+
## Use cases
|
|
99
|
+
|
|
100
|
+
- **Type-safe bindings**: paths for `@bind`, `@subscribe`, `@publish`
|
|
101
|
+
- **Dynamic paths**: reusable keys with `${...}` placeholders
|
|
102
|
+
- **Form fields**: form data paths with compile-time checking
|
|
103
|
+
|
|
104
|
+
## Integration with @subscribe and @publish
|
|
105
|
+
|
|
106
|
+
Use `DataProviderKey` with `@subscribe` (read-only) or `@publish` (write-only). The decorated property **must** match the key’s value type:
|
|
107
|
+
|
|
108
|
+
<sonic-code language="typescript">
|
|
109
|
+
<template>
|
|
110
|
+
import { subscribe } from "@supersoniks/concorde/decorators";
|
|
111
|
+
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
|
|
112
|
+
//
|
|
113
|
+
type FormData = { email: string };
|
|
114
|
+
const formKey = new DataProviderKey<FormData>("formData");
|
|
115
|
+
//
|
|
116
|
+
@customElement("user-form")
|
|
117
|
+
export class UserForm extends LitElement {
|
|
118
|
+
@subscribe(formKey.email)
|
|
119
|
+
@state()
|
|
120
|
+
email = "";
|
|
121
|
+
//
|
|
122
|
+
render() {
|
|
123
|
+
return html`<input .value=${this.email} @input=${(e) => this.email = (e.target as HTMLInputElement).value}>`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
</template>
|
|
127
|
+
</sonic-code>
|
|
128
|
+
|
|
129
|
+
Both decorators support dynamic paths: `"base.${prop}"` in the constructor. A wrong property type (e.g. `number` for `DataProviderKey<string>`) is a TypeScript error.
|
|
130
|
+
|
|
131
|
+
## Notes
|
|
132
|
+
|
|
133
|
+
- Function properties are excluded from navigation (no `key.method()` chaining)
|
|
134
|
+
- Primitives have no navigable properties
|
|
135
|
+
- The `path` property and `toString()` are equivalent for retrieving the key
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Endpoint
|
|
2
|
+
|
|
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
|
+
|
|
5
|
+
The optional second generic `U` (default `any`) describes host properties used to resolve dynamic segments in the path (`${…}` / `{$…}`), for example with the [@get](#docs/_decorators/get.md/get) decorator.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
<sonic-code language="typescript">
|
|
10
|
+
<template>
|
|
11
|
+
import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
|
|
12
|
+
</template>
|
|
13
|
+
</sonic-code>
|
|
14
|
+
|
|
15
|
+
## Construction
|
|
16
|
+
|
|
17
|
+
<sonic-code language="typescript">
|
|
18
|
+
<template>
|
|
19
|
+
const users = new Endpoint<User[]>("users?limit=10");
|
|
20
|
+
users.path; // "users?limit=10"
|
|
21
|
+
//
|
|
22
|
+
const one = new Endpoint<User, { userId: string }>("users/${userId}");
|
|
23
|
+
// `userId` on the host class is observed when used with @get
|
|
24
|
+
</template>
|
|
25
|
+
</sonic-code>
|
|
26
|
+
|
|
27
|
+
## Normalization
|
|
28
|
+
|
|
29
|
+
`Endpoint.normalizePath` trims the string, rejects an empty path, strips leading slashes for paths relative to `serviceURL`, collapses duplicate slashes, and validates absolute `http(s)://` URLs.
|
|
30
|
+
|
|
31
|
+
## Publisher key for payloads
|
|
32
|
+
|
|
33
|
+
`getDataProviderKey()` returns a typed publisher key whose `path` matches the endpoint path (payload typing follows `ApiGetResult` for this endpoint). Useful when pairing `@get` with `@publish` / `@subscribe` (see [@get](#docs/_decorators/get.md/get)).
|
|
34
|
+
|
|
35
|
+
## Data-provider paths
|
|
36
|
+
|
|
37
|
+
`Endpoint.looksLikeDataProviderPath(path)` returns true for strings shaped like `dataProvider(id)…`, which `API.get` can resolve without HTTP.
|
|
38
|
+
|
|
39
|
+
## See also
|
|
40
|
+
|
|
41
|
+
- [@get](#docs/_decorators/get.md/get) — decorator that uses `Endpoint<T>`
|
|
42
|
+
- [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey) — typed publisher paths (dot notation)
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { html, LitElement } from "lit";
|
|
2
|
+
import { customElement, property, state } from "lit/decorators.js";
|
|
3
|
+
import { bind } from "@supersoniks/concorde/decorators";
|
|
4
|
+
import { DataProviderKey } from "@supersoniks/concorde/core/utils/dataProviderKey";
|
|
5
|
+
import { sub } from "@supersoniks/concorde/directives";
|
|
6
|
+
import {
|
|
7
|
+
PublisherManager,
|
|
8
|
+
PublisherProxy,
|
|
9
|
+
} from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
10
|
+
import { Objects } from "@supersoniks/concorde/utils";
|
|
11
|
+
import { tailwind } from "../tailwind";
|
|
12
|
+
import "./decorators-demo-init";
|
|
13
|
+
|
|
14
|
+
@customElement("demo-bind")
|
|
15
|
+
export class DemoBind extends LitElement {
|
|
16
|
+
static styles = [tailwind];
|
|
17
|
+
|
|
18
|
+
@bind("demoData.firstName")
|
|
19
|
+
@state()
|
|
20
|
+
firstName = "";
|
|
21
|
+
|
|
22
|
+
@bind("demoData.lastName")
|
|
23
|
+
@state()
|
|
24
|
+
lastName: string = "";
|
|
25
|
+
|
|
26
|
+
@bind("demoData.count")
|
|
27
|
+
@state()
|
|
28
|
+
count: number = 0;
|
|
29
|
+
|
|
30
|
+
render() {
|
|
31
|
+
return html`
|
|
32
|
+
<div>
|
|
33
|
+
<sonic-button @click=${this.updateData}>Update Data</sonic-button>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="p-3">
|
|
36
|
+
<p>Title: <strong>${this.firstName || "Not set"}</strong></p>
|
|
37
|
+
<p>User Name: <strong>${this.lastName || "Not set"}</strong></p>
|
|
38
|
+
<p>Number of updates: <strong>${this.count}</strong></p>
|
|
39
|
+
</div>
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
updateData() {
|
|
44
|
+
const demoData = PublisherManager.get("demoData");
|
|
45
|
+
const demoUsers = PublisherManager.get("demoUsers");
|
|
46
|
+
const randomIndex = Math.floor(Math.random() * demoUsers.get().length);
|
|
47
|
+
const randomUser = demoUsers.get()[randomIndex];
|
|
48
|
+
demoData.set({
|
|
49
|
+
firstName: randomUser.firstName,
|
|
50
|
+
lastName: randomUser.lastName,
|
|
51
|
+
count: (demoData.count.get() || 0) + 1,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@customElement("demo-bind-reflect")
|
|
57
|
+
export class DemoBindReflect extends LitElement {
|
|
58
|
+
static styles = [tailwind];
|
|
59
|
+
|
|
60
|
+
@bind("bindReflectDemo.count", { reflect: true })
|
|
61
|
+
@state()
|
|
62
|
+
withReflect: number = 0;
|
|
63
|
+
|
|
64
|
+
@bind("bindReflectDemo.count")
|
|
65
|
+
@state()
|
|
66
|
+
withoutReflect: number = 0;
|
|
67
|
+
|
|
68
|
+
connectedCallback() {
|
|
69
|
+
super.connectedCallback();
|
|
70
|
+
this.resetData();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
resetData() {
|
|
74
|
+
PublisherManager.get("bindReflectDemo").set({ count: 0 });
|
|
75
|
+
}
|
|
76
|
+
render() {
|
|
77
|
+
return html`
|
|
78
|
+
<div class="mb-3">
|
|
79
|
+
from publisher : ${sub("bindReflectDemo.count")} <br />
|
|
80
|
+
from component with reflect : ${this.withReflect} <br />
|
|
81
|
+
from component without reflect : ${this.withoutReflect}
|
|
82
|
+
</div>
|
|
83
|
+
<sonic-button @click=${() => this.withReflect++}
|
|
84
|
+
>Increment with reflect</sonic-button
|
|
85
|
+
>
|
|
86
|
+
<sonic-button @click=${() => this.withoutReflect++}
|
|
87
|
+
>Increment without reflect</sonic-button
|
|
88
|
+
>
|
|
89
|
+
<sonic-button @click=${this.resetData}>Reset publisher data</sonic-button>
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
type BindReflectDemoData = { count: number };
|
|
95
|
+
const bindReflectDemoKey = new DataProviderKey<BindReflectDemoData>("bindReflectDemo");
|
|
96
|
+
|
|
97
|
+
@customElement("demo-bind-key")
|
|
98
|
+
export class DemoBindKey extends LitElement {
|
|
99
|
+
static styles = [tailwind];
|
|
100
|
+
|
|
101
|
+
@bind(bindReflectDemoKey.count, { reflect: true })
|
|
102
|
+
@state()
|
|
103
|
+
count: number = 0;
|
|
104
|
+
|
|
105
|
+
connectedCallback() {
|
|
106
|
+
super.connectedCallback();
|
|
107
|
+
PublisherManager.get("bindReflectDemo").set({ count: 0 });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
render() {
|
|
111
|
+
return html`
|
|
112
|
+
<div class="mb-3">
|
|
113
|
+
<p>@bind with DataProviderKey<number> (type-safe): ${this.count}</p>
|
|
114
|
+
</div>
|
|
115
|
+
<sonic-button @click=${() => this.count++}>Increment</sonic-button>
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@customElement("demo-bind-dynamic")
|
|
121
|
+
export class DemoBindDynamic extends LitElement {
|
|
122
|
+
static styles = [tailwind];
|
|
123
|
+
|
|
124
|
+
@property({ type: String })
|
|
125
|
+
dataProvider: "demoUsers" | "demoUsersAlt" = "demoUsers";
|
|
126
|
+
|
|
127
|
+
@property({ type: Number })
|
|
128
|
+
userIndex: number = 1;
|
|
129
|
+
|
|
130
|
+
@bind("${dataProvider}.${userIndex}")
|
|
131
|
+
@state()
|
|
132
|
+
user: any = {};
|
|
133
|
+
|
|
134
|
+
updateUserIndex(e: Event) {
|
|
135
|
+
this.userIndex = parseInt((e.target as HTMLInputElement).value);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
updateDataProvider(e: Event) {
|
|
139
|
+
this.dataProvider = (e.target as HTMLSelectElement).value as
|
|
140
|
+
| "demoUsers"
|
|
141
|
+
| "demoUsersAlt";
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
updateCurrentUserData() {
|
|
145
|
+
const usersPublisher = PublisherManager.get(this.dataProvider);
|
|
146
|
+
const userPublisher = Objects.traverse(usersPublisher, [
|
|
147
|
+
String(this.userIndex),
|
|
148
|
+
]) as PublisherProxy;
|
|
149
|
+
|
|
150
|
+
if (userPublisher) {
|
|
151
|
+
const randomNames = [
|
|
152
|
+
{ firstName: "Alice", lastName: "Wonder" },
|
|
153
|
+
{ firstName: "Bob", lastName: "Builder" },
|
|
154
|
+
{ firstName: "Charlie", lastName: "Chaplin" },
|
|
155
|
+
{ firstName: "Diana", lastName: "Prince" },
|
|
156
|
+
{ firstName: "Eve", lastName: "Adams" },
|
|
157
|
+
];
|
|
158
|
+
|
|
159
|
+
const randomName =
|
|
160
|
+
randomNames[Math.floor(Math.random() * randomNames.length)];
|
|
161
|
+
const randomEmail = `${randomName.firstName.toLowerCase()}.${randomName.lastName.toLowerCase()}@example.com`;
|
|
162
|
+
|
|
163
|
+
const currentUser = userPublisher.get() || {};
|
|
164
|
+
userPublisher.set({
|
|
165
|
+
...currentUser,
|
|
166
|
+
firstName: randomName.firstName,
|
|
167
|
+
lastName: randomName.lastName,
|
|
168
|
+
email: randomEmail,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
render() {
|
|
174
|
+
return html`
|
|
175
|
+
<div class="flex flex-col gap-2">
|
|
176
|
+
<sonic-select
|
|
177
|
+
.value=${this.dataProvider}
|
|
178
|
+
label="Users set"
|
|
179
|
+
@change=${this.updateDataProvider}
|
|
180
|
+
>
|
|
181
|
+
<option value="demoUsers">First set of users</option>
|
|
182
|
+
<option value="demoUsersAlt">Second set of users</option>
|
|
183
|
+
</sonic-select>
|
|
184
|
+
<sonic-input
|
|
185
|
+
type="number"
|
|
186
|
+
.value=${this.userIndex}
|
|
187
|
+
@input=${this.updateUserIndex}
|
|
188
|
+
min="0"
|
|
189
|
+
max="9"
|
|
190
|
+
label="Index"
|
|
191
|
+
class="block"
|
|
192
|
+
>
|
|
193
|
+
</sonic-input>
|
|
194
|
+
<sonic-button @click=${this.updateCurrentUserData}
|
|
195
|
+
>Update current user data</sonic-button
|
|
196
|
+
>
|
|
197
|
+
<div class="flex flex-col gap-2 border p-2">
|
|
198
|
+
<div>
|
|
199
|
+
<sonic-icon name="user" library="heroicons"></sonic-icon>
|
|
200
|
+
${this.user?.firstName} ${this.user?.lastName}
|
|
201
|
+
</div>
|
|
202
|
+
<div>
|
|
203
|
+
<sonic-icon name="envelope" library="heroicons"></sonic-icon>
|
|
204
|
+
${this.user?.email}
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
`;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { APIConfiguration } from "@supersoniks/concorde/core/utils/api";
|
|
2
|
+
import type { ApiGetResult } from "@supersoniks/concorde/core/utils/api";
|
|
3
|
+
import { Endpoint } from "@supersoniks/concorde/core/utils/endpoint";
|
|
4
|
+
import { DataProviderKey } from "@supersoniks/concorde/core/utils/dataProviderKey";
|
|
5
|
+
import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
6
|
+
import "./decorators-demo-init";
|
|
7
|
+
|
|
8
|
+
export type GeoCommuneRow = { nom: string; code: string };
|
|
9
|
+
|
|
10
|
+
export const geoApiDemoConfiguration: APIConfiguration = {
|
|
11
|
+
serviceURL: "https://geo.api.gouv.fr/",
|
|
12
|
+
token: null,
|
|
13
|
+
userName: null,
|
|
14
|
+
password: null,
|
|
15
|
+
authToken: null,
|
|
16
|
+
tokenProvider: null,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const docsDemoGeoApiConfigurationId = "docsDemoGeoApiConfiguration";
|
|
20
|
+
PublisherManager.get(docsDemoGeoApiConfigurationId).set(geoApiDemoConfiguration);
|
|
21
|
+
|
|
22
|
+
export const docsDemoGeoApiConfigurationKey = new DataProviderKey<APIConfiguration>(
|
|
23
|
+
docsDemoGeoApiConfigurationId,
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export const geoCommunesApiGetEndpoint = new Endpoint<GeoCommuneRow[]>(
|
|
27
|
+
"communes?limit=5&fields=nom,code",
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export const docsDemoDynApiConfKeyTemplate = new DataProviderKey<APIConfiguration>(
|
|
31
|
+
"docsDemoDynApiConf${configSlot}",
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
PublisherManager.get("docsDemoDynApiConfA").set(geoApiDemoConfiguration);
|
|
35
|
+
PublisherManager.get("docsDemoDynApiConfB").set({
|
|
36
|
+
...geoApiDemoConfiguration,
|
|
37
|
+
serviceURL: "https://geo.api.gouv.fr/",
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export const geoCommunesApiGetEndpointDynamic = new Endpoint<GeoCommuneRow[]>(
|
|
41
|
+
"communes?limit=${communeLimit}&fields=nom,code",
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
export const geoCommunesApiGetPublishKey =
|
|
45
|
+
new DataProviderKey<ApiGetResult<GeoCommuneRow[]>>(geoCommunesApiGetEndpoint.path);
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
2
|
+
|
|
3
|
+
export const ensurePublisherValue = <T>(
|
|
4
|
+
publisherId: string,
|
|
5
|
+
defaultValue: T,
|
|
6
|
+
): void => {
|
|
7
|
+
const publisher = PublisherManager.get(publisherId);
|
|
8
|
+
const currentValue =
|
|
9
|
+
typeof publisher.get === "function" ? publisher.get() : undefined;
|
|
10
|
+
|
|
11
|
+
const isUnset =
|
|
12
|
+
currentValue === undefined ||
|
|
13
|
+
currentValue === null ||
|
|
14
|
+
(typeof currentValue === "object" &&
|
|
15
|
+
!Array.isArray(currentValue) &&
|
|
16
|
+
Object.keys(currentValue).length === 0);
|
|
17
|
+
|
|
18
|
+
if (isUnset) {
|
|
19
|
+
publisher.set(defaultValue as T);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const initializeDecoratorsDemoData = () => {
|
|
24
|
+
ensurePublisherValue("demoData", {
|
|
25
|
+
title: "Initial Title",
|
|
26
|
+
user: { name: "Initial User" },
|
|
27
|
+
count: 0,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
ensurePublisherValue("demoUser", {
|
|
31
|
+
name: "Demo User",
|
|
32
|
+
email: "demo@example.com",
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
ensurePublisherValue("demoSettings", {
|
|
36
|
+
theme: "light",
|
|
37
|
+
language: "en",
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
ensurePublisherValue("demoUserSettings", {
|
|
41
|
+
theme: "light",
|
|
42
|
+
language: "en",
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
ensurePublisherValue("autoValue1", 10);
|
|
46
|
+
ensurePublisherValue("autoValue2", 20);
|
|
47
|
+
ensurePublisherValue("waitAncestorDemo", {
|
|
48
|
+
message: "Context from ancestor",
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
ensurePublisherValue("combinedData", { title: "Combined Title" });
|
|
52
|
+
ensurePublisherValue("combinedUser", { name: "Combined User" });
|
|
53
|
+
ensurePublisherValue("combinedSettings", { theme: "dark" });
|
|
54
|
+
|
|
55
|
+
ensurePublisherValue("reflectData", {
|
|
56
|
+
title: "Initial Reflected Title",
|
|
57
|
+
count: 0,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
ensurePublisherValue("publishDemo", {
|
|
61
|
+
email: "",
|
|
62
|
+
message: "",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
ensurePublisherValue("dynamicProfiles", {
|
|
66
|
+
alpha: { info: { title: "Profil Alpha" } },
|
|
67
|
+
beta: { info: { title: "Profil Beta" } },
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
ensurePublisherValue("dynamicProfilesAlt", {
|
|
71
|
+
alpha: { info: { title: "Profil Alpha (Alt)" } },
|
|
72
|
+
beta: { info: { title: "Profil Beta (Alt)" } },
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
ensurePublisherValue("demoUsers", [
|
|
76
|
+
{
|
|
77
|
+
id: 1,
|
|
78
|
+
firstName: "Alice",
|
|
79
|
+
lastName: "Smith",
|
|
80
|
+
email: "alice.smith@example.com",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: 2,
|
|
84
|
+
firstName: "Bob",
|
|
85
|
+
lastName: "Johnson",
|
|
86
|
+
email: "bob.johnson@example.com",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 3,
|
|
90
|
+
firstName: "Carol",
|
|
91
|
+
lastName: "Williams",
|
|
92
|
+
email: "carol.williams@example.com",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 4,
|
|
96
|
+
firstName: "David",
|
|
97
|
+
lastName: "Brown",
|
|
98
|
+
email: "david.brown@example.com",
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: 5,
|
|
102
|
+
firstName: "Eve",
|
|
103
|
+
lastName: "Jones",
|
|
104
|
+
email: "eve.jones@example.com",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 6,
|
|
108
|
+
firstName: "Frank",
|
|
109
|
+
lastName: "Garcia",
|
|
110
|
+
email: "frank.garcia@example.com",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: 7,
|
|
114
|
+
firstName: "Grace",
|
|
115
|
+
lastName: "Miller",
|
|
116
|
+
email: "grace.miller@example.com",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: 8,
|
|
120
|
+
firstName: "Henry",
|
|
121
|
+
lastName: "Davis",
|
|
122
|
+
email: "henry.davis@example.com",
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: 9,
|
|
126
|
+
firstName: "Ivy",
|
|
127
|
+
lastName: "Martinez",
|
|
128
|
+
email: "ivy.martinez@example.com",
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: 10,
|
|
132
|
+
firstName: "Jack",
|
|
133
|
+
lastName: "Taylor",
|
|
134
|
+
email: "jack.taylor@example.com",
|
|
135
|
+
},
|
|
136
|
+
]);
|
|
137
|
+
|
|
138
|
+
ensurePublisherValue("demoUsersAlt", [
|
|
139
|
+
{
|
|
140
|
+
id: 11,
|
|
141
|
+
firstName: "Sophie",
|
|
142
|
+
lastName: "Lindquist",
|
|
143
|
+
email: "sophie.lindquist@example.com",
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
id: 12,
|
|
147
|
+
firstName: "Mateo",
|
|
148
|
+
lastName: "Ortega",
|
|
149
|
+
email: "mateo.ortega@example.com",
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: 13,
|
|
153
|
+
firstName: "Jin",
|
|
154
|
+
lastName: "Park",
|
|
155
|
+
email: "jin.park@example.com",
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
id: 14,
|
|
159
|
+
firstName: "Fatima",
|
|
160
|
+
lastName: "El-Sayed",
|
|
161
|
+
email: "fatima.el-sayed@example.com",
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: 15,
|
|
165
|
+
firstName: "Lars",
|
|
166
|
+
lastName: "Johansson",
|
|
167
|
+
email: "lars.johansson@example.com",
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: 16,
|
|
171
|
+
firstName: "Amara",
|
|
172
|
+
lastName: "Singh",
|
|
173
|
+
email: "amara.singh@example.com",
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
id: 17,
|
|
177
|
+
firstName: "Zuri",
|
|
178
|
+
lastName: "Okafor",
|
|
179
|
+
email: "zuri.okafor@example.com",
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
id: 18,
|
|
183
|
+
firstName: "Luca",
|
|
184
|
+
lastName: "Rossi",
|
|
185
|
+
email: "luca.rossi@example.com",
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: 19,
|
|
189
|
+
firstName: "Ava",
|
|
190
|
+
lastName: "Murphy",
|
|
191
|
+
email: "ava.murphy@example.com",
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
id: 20,
|
|
195
|
+
firstName: "Noah",
|
|
196
|
+
lastName: "Keller",
|
|
197
|
+
email: "noah.keller@example.com",
|
|
198
|
+
},
|
|
199
|
+
]);
|
|
200
|
+
|
|
201
|
+
ensurePublisherValue("demoUsersSettings", [
|
|
202
|
+
{ theme: "light", language: "en" },
|
|
203
|
+
{ theme: "dark", language: "fr" },
|
|
204
|
+
{ theme: "auto", language: "es" },
|
|
205
|
+
{ theme: "light", language: "en" },
|
|
206
|
+
{ theme: "dark", language: "fr" },
|
|
207
|
+
{ theme: "auto", language: "es" },
|
|
208
|
+
{ theme: "light", language: "en" },
|
|
209
|
+
{ theme: "dark", language: "fr" },
|
|
210
|
+
{ theme: "auto", language: "es" },
|
|
211
|
+
{ theme: "light", language: "en" },
|
|
212
|
+
]);
|
|
213
|
+
|
|
214
|
+
ensurePublisherValue("demoUsersAltSettings", [
|
|
215
|
+
{ theme: "dark", language: "de" },
|
|
216
|
+
{ theme: "light", language: "it" },
|
|
217
|
+
{ theme: "auto", language: "ja" },
|
|
218
|
+
{ theme: "dark", language: "pt" },
|
|
219
|
+
{ theme: "light", language: "ru" },
|
|
220
|
+
{ theme: "auto", language: "zh" },
|
|
221
|
+
{ theme: "dark", language: "ar" },
|
|
222
|
+
{ theme: "light", language: "sv" },
|
|
223
|
+
{ theme: "auto", language: "nl" },
|
|
224
|
+
{ theme: "dark", language: "pl" },
|
|
225
|
+
]);
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
initializeDecoratorsDemoData();
|