@aastrika/ai-elements 0.1.0 → 0.2.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 +291 -46
- package/aastrika-elements.d.ts +148 -12
- package/aastrika-elements.js +9 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,101 @@
|
|
|
1
1
|
# @aastrika/ai-elements
|
|
2
2
|
|
|
3
|
-
Three Aastrika features as custom elements
|
|
4
|
-
or plain HTML.
|
|
3
|
+
**Three Aastrika features as custom elements.** Works in React, Vue, Angular,
|
|
4
|
+
Svelte or plain HTML.
|
|
5
5
|
|
|
6
|
+
| Tag | What it does |
|
|
7
|
+
|---|---|
|
|
8
|
+
| `<aastrika-content-studio>` | A document becomes a narrated, illustrated training video |
|
|
9
|
+
| `<aastrika-assessment>` | Source material becomes a validated MCQ set |
|
|
10
|
+
| `<aastrika-reports>` | Who used what, and what it cost *(admin only)* |
|
|
11
|
+
|
|
12
|
+
One file, **86 kB** over the wire, **no dependencies**. Angular is compiled
|
|
13
|
+
inside, so you never install it and never upgrade because we did.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Contents
|
|
18
|
+
|
|
19
|
+
| | |
|
|
20
|
+
|---|---|
|
|
21
|
+
| [The three features](#the-three-features) | What each element does |
|
|
22
|
+
| [Setup](#setup) | Install, access, configure, mount |
|
|
23
|
+
| [Framework notes](#framework-notes) | React · Angular · Plain HTML |
|
|
24
|
+
| [Configuration](#configuration) | The three values, and why two are functions |
|
|
25
|
+
| [Access](#access) | Which gateway groups each feature needs |
|
|
26
|
+
| [Theming](#theming) | CSS custom properties |
|
|
27
|
+
| [Knowing when something failed](#knowing-when-something-failed) | Routing errors to your monitoring |
|
|
28
|
+
| [Inputs and events](#inputs-and-events) | Opening the form set up, and acting on the result |
|
|
29
|
+
| [When it does not work](#when-it-does-not-work) | Symptom → cause |
|
|
30
|
+
| [Browser support](#browser-support) · [Server rendering](#server-rendering) | Constraints |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Quick start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm i @aastrika/ai-elements
|
|
6
38
|
```
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
import { configure } from '@aastrika/ai-elements';
|
|
42
|
+
|
|
43
|
+
configure({
|
|
44
|
+
apiBase: 'https://api.aastrika.org/ai-studio',
|
|
45
|
+
getAuthHeaders: async () => ({ Authorization: `Bearer ${await auth.token()}` }),
|
|
46
|
+
creator: () => currentUser.username,
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<aastrika-content-studio></aastrika-content-studio>
|
|
10
52
|
```
|
|
11
53
|
|
|
12
|
-
|
|
13
|
-
|
|
54
|
+
That is the whole integration. The rest of this file is detail.
|
|
55
|
+
|
|
56
|
+
> **You also need gateway access.** The package authenticates nobody — see
|
|
57
|
+
> [Access](#access) for the groups each feature requires.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## How it fits together
|
|
62
|
+
|
|
63
|
+
```mermaid
|
|
64
|
+
flowchart LR
|
|
65
|
+
subgraph host["Your application"]
|
|
66
|
+
cfg["configure()"]
|
|
67
|
+
tag["<aastrika-content-studio>"]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
subgraph pkg["@aastrika/ai-elements"]
|
|
71
|
+
el["Custom element"]
|
|
72
|
+
int["Interceptor"]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
subgraph svc["Aastrika"]
|
|
76
|
+
gw["Gateway<br/>checks the token"]
|
|
77
|
+
api["AI service"]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
cfg -.->|apiBase · auth · creator| int
|
|
81
|
+
tag --> el
|
|
82
|
+
el --> int
|
|
83
|
+
int -->|"Authorization<br/>x-aastrika-creator"| gw
|
|
84
|
+
gw --> api
|
|
85
|
+
api -.->|JSON| el
|
|
86
|
+
el -.->|onError| cfg
|
|
87
|
+
|
|
88
|
+
classDef a fill:#0F766E,stroke:none,color:#fff
|
|
89
|
+
classDef b fill:#f1f5f4,stroke:#cbd5d3,color:#16181d
|
|
90
|
+
class el,int a
|
|
91
|
+
class cfg,tag,gw,api b
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Your application supplies three values. The package does the rest** — builds
|
|
95
|
+
every request from `apiBase`, calls your two functions on each one, and renders
|
|
96
|
+
into your page, styled through CSS custom properties.
|
|
97
|
+
|
|
98
|
+
---
|
|
14
99
|
|
|
15
100
|
## The three features
|
|
16
101
|
|
|
@@ -50,63 +135,113 @@ apart.
|
|
|
50
135
|
|
|
51
136
|
[Full walkthrough →](features/reports/README.md)
|
|
52
137
|
|
|
138
|
+
---
|
|
139
|
+
|
|
53
140
|
## Setup
|
|
54
141
|
|
|
55
|
-
|
|
142
|
+
The [Quick start](#quick-start) above is the whole integration. What each step
|
|
143
|
+
is actually doing:
|
|
56
144
|
|
|
57
|
-
|
|
58
|
-
|
|
145
|
+
| | Step | Notes |
|
|
146
|
+
|---|---|---|
|
|
147
|
+
| **1** | `npm i @aastrika/ai-elements` | No peer dependencies, no framework to match. Any bundler, or none |
|
|
148
|
+
| **2** | Get gateway access | The package authenticates nobody — your gateway decides. See [Access](#access), then ask the Aastrika platform team |
|
|
149
|
+
| **3** | `configure({ ... })` | Once, before the first element renders. Two of the three values are **functions** — see [Configuration](#configuration) |
|
|
150
|
+
| **4** | Write the tag | Registration happens on import, so there is no third step |
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Framework notes
|
|
155
|
+
|
|
156
|
+
### React
|
|
157
|
+
|
|
158
|
+
```jsx
|
|
159
|
+
import '@aastrika/ai-elements';
|
|
160
|
+
|
|
161
|
+
<aastrika-content-studio />
|
|
59
162
|
```
|
|
60
163
|
|
|
61
|
-
|
|
164
|
+
React 19 passes properties and custom events natively — no wrapper, no `ref`.
|
|
62
165
|
|
|
63
|
-
###
|
|
166
|
+
### Angular
|
|
64
167
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
you need a Kong consumer with the right groups. See [Access](#access) for which
|
|
68
|
-
feature needs which, and ask the Aastrika platform team to set it up.
|
|
168
|
+
Two steps: call `configure()` once at bootstrap, then add
|
|
169
|
+
`CUSTOM_ELEMENTS_SCHEMA` to whichever component writes the tag.
|
|
69
170
|
|
|
70
|
-
|
|
171
|
+
**1. Configure at bootstrap** — `main.ts`, or an `APP_INITIALIZER` if the values
|
|
172
|
+
come from something you have to load first:
|
|
71
173
|
|
|
72
|
-
```
|
|
174
|
+
```ts
|
|
73
175
|
import { configure } from '@aastrika/ai-elements';
|
|
176
|
+
import { environment } from './environments/environment';
|
|
74
177
|
|
|
75
178
|
configure({
|
|
76
|
-
apiBase:
|
|
77
|
-
getAuthHeaders: async () => ({ Authorization: `Bearer ${await
|
|
78
|
-
creator: () =>
|
|
179
|
+
apiBase: environment.aastrikaApiBase,
|
|
180
|
+
getAuthHeaders: async () => ({ Authorization: `Bearer ${await authService.token()}` }),
|
|
181
|
+
creator: () => authService.username(),
|
|
79
182
|
});
|
|
183
|
+
|
|
184
|
+
bootstrapApplication(AppComponent, appConfig);
|
|
80
185
|
```
|
|
81
186
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
session that keeps working and one that dies when the token expires.
|
|
187
|
+
Import order matters: the import registers the three tags as a side effect, so it
|
|
188
|
+
has to run before Angular renders a template containing one.
|
|
85
189
|
|
|
86
|
-
|
|
190
|
+
**2. Host the tag**
|
|
87
191
|
|
|
88
|
-
```
|
|
89
|
-
|
|
192
|
+
```ts
|
|
193
|
+
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
194
|
+
|
|
195
|
+
@Component({
|
|
196
|
+
selector: 'app-training',
|
|
197
|
+
standalone: true,
|
|
198
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
199
|
+
template: `<aastrika-content-studio></aastrika-content-studio>`,
|
|
200
|
+
})
|
|
201
|
+
export class TrainingComponent {}
|
|
90
202
|
```
|
|
91
203
|
|
|
92
|
-
|
|
204
|
+
<details>
|
|
205
|
+
<summary><strong>Routing, styling, and why the schema matters</strong></summary>
|
|
93
206
|
|
|
94
|
-
|
|
207
|
+
`CUSTOM_ELEMENTS_SCHEMA` switches off template checking for **every** unknown
|
|
208
|
+
tag in that component, not just ours — which is why the package ships tag
|
|
209
|
+
declarations. They give it back for these three, so a typo in
|
|
210
|
+
`aastrika-assessment` is still an error rather than a silently empty box.
|
|
95
211
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
212
|
+
**Little else to wire.** `apiBase`, the auth headers and the creator all come
|
|
213
|
+
from `configure()`, and each element manages its own state, so there is no
|
|
214
|
+
cleanup to write. Beyond that there are optional
|
|
215
|
+
[inputs and events](#inputs-and-events) — and `edit-mode`, which is worth
|
|
216
|
+
knowing about up front:
|
|
100
217
|
|
|
101
|
-
|
|
218
|
+
```html
|
|
219
|
+
<aastrika-content-studio edit-mode="on"></aastrika-content-studio>
|
|
102
220
|
```
|
|
103
221
|
|
|
104
|
-
|
|
222
|
+
`edit-mode` turns on the segment editor for an uploaded video, and defaults to
|
|
223
|
+
`off`. Leave it off unless the host is **same-origin** with the service: the
|
|
224
|
+
editor loads per-segment thumbnails the service streams off local disk, and
|
|
225
|
+
unlike the finished video those have no presigned URL, so they cannot load from
|
|
226
|
+
another origin. The other two elements take no attributes.
|
|
105
227
|
|
|
106
|
-
|
|
228
|
+
**Routing** works normally — put the tag in a lazily loaded route and the element
|
|
229
|
+
mounts on navigation, unmounts on leaving.
|
|
230
|
+
|
|
231
|
+
**Styling** goes through CSS custom properties. Angular's view encapsulation
|
|
232
|
+
rewrites a component-scoped rule into something that will not match the
|
|
233
|
+
element, so set the properties from a global stylesheet:
|
|
234
|
+
|
|
235
|
+
```css
|
|
236
|
+
/* styles.css */
|
|
237
|
+
aastrika-content-studio { --aastrika-gold: #0F766E; }
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**A blank box** almost always means `configure()` ran after the template, or the
|
|
241
|
+
import was tree-shaken because nothing referenced it. Importing `configure` and
|
|
242
|
+
calling it, as above, prevents both.
|
|
107
243
|
|
|
108
|
-
|
|
109
|
-
ships tag declarations, so these three keep their template checking.
|
|
244
|
+
</details>
|
|
110
245
|
|
|
111
246
|
### Plain HTML
|
|
112
247
|
|
|
@@ -115,6 +250,8 @@ ships tag declarations, so these three keep their template checking.
|
|
|
115
250
|
<aastrika-content-studio></aastrika-content-studio>
|
|
116
251
|
```
|
|
117
252
|
|
|
253
|
+
---
|
|
254
|
+
|
|
118
255
|
## Configuration
|
|
119
256
|
|
|
120
257
|
Three things, and nothing else.
|
|
@@ -124,6 +261,7 @@ Three things, and nothing else.
|
|
|
124
261
|
| `apiBase` | Where the service is, no trailing slash. Empty string means same-origin. |
|
|
125
262
|
| `getAuthHeaders` | Headers proving the caller may use the service — in practice a bearer token. |
|
|
126
263
|
| `creator` | The username of whoever is signed into **your** application. |
|
|
264
|
+
| `onError` | Optional. Called whenever a request fails, so your monitoring hears about it. |
|
|
127
265
|
|
|
128
266
|
**Both are functions, and both are called on every request.** Tokens expire: a
|
|
129
267
|
string handed over at startup stops working mid-session and the package has no
|
|
@@ -137,6 +275,8 @@ gateway decides whether the call is allowed at all.
|
|
|
137
275
|
The package authenticates nobody and has no login of its own. You are already
|
|
138
276
|
signed in, and you know who that is better than we could.
|
|
139
277
|
|
|
278
|
+
---
|
|
279
|
+
|
|
140
280
|
## Access
|
|
141
281
|
|
|
142
282
|
Ask the Aastrika platform team for a Kong consumer with the groups each feature
|
|
@@ -154,11 +294,11 @@ features still work, but the revise step returns 403.
|
|
|
154
294
|
> **`generate-video` is the only call that spends real money**, and it sits on a
|
|
155
295
|
> deliberately low rate limit. Users see a cost estimate before triggering it.
|
|
156
296
|
|
|
297
|
+
---
|
|
298
|
+
|
|
157
299
|
## Theming
|
|
158
300
|
|
|
159
|
-
CSS custom properties are the
|
|
160
|
-
a shadow root, so your CSS cannot reach in — and the package cannot reach out
|
|
161
|
-
and break your layout.
|
|
301
|
+
CSS custom properties are the styling surface:
|
|
162
302
|
|
|
163
303
|
```css
|
|
164
304
|
aastrika-content-studio {
|
|
@@ -168,14 +308,93 @@ aastrika-content-studio {
|
|
|
168
308
|
}
|
|
169
309
|
```
|
|
170
310
|
|
|
171
|
-
|
|
311
|
+
**These render into your page, not a shadow root.** Angular's emulated view
|
|
312
|
+
encapsulation scopes the package's own CSS, so it will not leak out and break
|
|
313
|
+
your layout. It does not stop your CSS reaching in: a global rule on a common
|
|
314
|
+
class name — `.card`, `.btn`, `.field` — will hit these elements too. If your
|
|
315
|
+
stylesheet is broad, scope it away from the three tags.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Knowing when something failed
|
|
320
|
+
|
|
321
|
+
The elements show their own error to the user. `onError` is the second copy, for
|
|
322
|
+
your monitoring:
|
|
323
|
+
|
|
324
|
+
```js
|
|
325
|
+
configure({
|
|
326
|
+
apiBase: '...',
|
|
327
|
+
onError: ({ feature, message, status, code }) => {
|
|
328
|
+
Sentry.captureMessage(`aastrika/${feature}: ${message}`, { extra: { status, code } });
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
| | |
|
|
334
|
+
|---|---|
|
|
335
|
+
| `feature` | `content-studio`, `assessment` or `reports` |
|
|
336
|
+
| `message` | The sentence shown to the user |
|
|
337
|
+
| `status` | HTTP status. **`0` means the request never left the browser** — usually CORS |
|
|
338
|
+
| `code` | The service's code, when it sent one, e.g. `RENDER_TIMEOUT` |
|
|
339
|
+
|
|
340
|
+
Without it, an element failing every call looks exactly like one nobody has
|
|
341
|
+
used yet. Throwing from inside it is safe — the exception is swallowed, so a
|
|
342
|
+
broken reporter cannot break the feature reporting to it.
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Inputs and events
|
|
347
|
+
|
|
348
|
+
Every element works with nothing bound. These are for hosts that want to open
|
|
349
|
+
the form already set up, or act on what the user produced.
|
|
350
|
+
|
|
351
|
+
### Inputs
|
|
352
|
+
|
|
353
|
+
Attributes in HTML, properties in JS — Angular Elements maps one to the other.
|
|
354
|
+
All are **starting values** the user can still change.
|
|
355
|
+
|
|
356
|
+
| Element | Input | |
|
|
357
|
+
|---|---|---|
|
|
358
|
+
| `content-studio` | `default-language` | `hi`, `en`, `kn`, `te` |
|
|
359
|
+
| | `default-aspect-ratio` | `16:9` or `9:16` |
|
|
360
|
+
| | `default-depth` | How much detail the video goes into |
|
|
361
|
+
| | `default-voice` | A voice id from `/v1/studio/list-voices` |
|
|
362
|
+
| | `edit-mode` | `on` shows the segment editor. Same-origin hosts only |
|
|
363
|
+
| `assessment` | `default-language` | |
|
|
364
|
+
| | `default-question-count` | |
|
|
365
|
+
| | `default-difficulty` | `mixed`, `easy`, `medium`, `hard` |
|
|
366
|
+
| `reports` | `creator-filter` | Opens filtered to one creator |
|
|
367
|
+
|
|
368
|
+
```html
|
|
369
|
+
<aastrika-content-studio default-language="kn" default-aspect-ratio="9:16">
|
|
370
|
+
</aastrika-content-studio>
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Events
|
|
374
|
+
|
|
375
|
+
| Element | Event | Fires when | `detail` |
|
|
376
|
+
|---|---|---|---|
|
|
377
|
+
| `content-studio` | `planReady` | A plan comes back. **Repeatable** — free, so this can fire several times | `jobId`, `title`, `sceneCount`, `estimatedUsd` |
|
|
378
|
+
| | `videoStarted` | The user commits to a render. **This is where money is spent** | `jobId` |
|
|
379
|
+
| | `videoReady` | The video is finished | `jobId`, `videoUrl` |
|
|
380
|
+
| `assessment` | `assessmentReady` | A validated question set comes back | `jobId`, `questionCount`, `language` |
|
|
381
|
+
| `reports` | `reportLoaded` | The figures are on screen | `videos`, `assessments`, `users`, `spendUsd` |
|
|
172
382
|
|
|
173
383
|
```js
|
|
174
|
-
el.addEventListener('
|
|
175
|
-
|
|
176
|
-
|
|
384
|
+
el.addEventListener('videoReady', (e) => {
|
|
385
|
+
saveToOurRecords(e.detail.jobId, e.detail.videoUrl);
|
|
386
|
+
});
|
|
177
387
|
```
|
|
178
388
|
|
|
389
|
+
`videoUrl` plays without an `Authorization` header, so it can go straight into a
|
|
390
|
+
`<video src>` or be stored as-is. It is null on the local storage driver, where
|
|
391
|
+
there is nothing to presign.
|
|
392
|
+
|
|
393
|
+
**React** passes properties and listeners natively. **Angular** binds them like
|
|
394
|
+
any DOM event: `(videoReady)="onReady($event)"`.
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
179
398
|
## When it does not work
|
|
180
399
|
|
|
181
400
|
| Symptom | Cause |
|
|
@@ -188,7 +407,33 @@ el.addEventListener('aastrika-error', (e) => toast(e.detail.message));
|
|
|
188
407
|
| Creator recorded as `unknown` | the gateway's CORS config is dropping `x-aastrika-creator` — tell us |
|
|
189
408
|
| Blank box, no errors | the module did not load, so the tag is an unknown element |
|
|
190
409
|
|
|
410
|
+
---
|
|
411
|
+
|
|
191
412
|
## Browser support
|
|
192
413
|
|
|
193
414
|
Any browser with Custom Elements v1 and Shadow DOM — everything since 2018.
|
|
194
|
-
|
|
415
|
+
|
|
416
|
+
## Server rendering
|
|
417
|
+
|
|
418
|
+
**Import this package only in browser code.** It is not server-renderable, and
|
|
419
|
+
the failure is a crash rather than an empty box: `@angular/elements` declares a
|
|
420
|
+
class extending `HTMLElement` at module scope, so merely importing the package
|
|
421
|
+
where there is no DOM throws `ReferenceError: HTMLElement is not defined`.
|
|
422
|
+
|
|
423
|
+
Next.js:
|
|
424
|
+
|
|
425
|
+
```jsx
|
|
426
|
+
import dynamic from 'next/dynamic';
|
|
427
|
+
|
|
428
|
+
const Studio = dynamic(
|
|
429
|
+
() => import('@aastrika/ai-elements').then(() => () => <aastrika-content-studio />),
|
|
430
|
+
{ ssr: false },
|
|
431
|
+
);
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
Angular Universal: keep the import inside a browser-only guard, or load it in
|
|
435
|
+
`ngAfterViewInit` rather than at module scope.
|
|
436
|
+
|
|
437
|
+
Nothing is lost by this. The elements have no server-rendered output to hydrate
|
|
438
|
+
— they fetch everything at runtime — so a client-only import renders exactly the
|
|
439
|
+
same page.
|
package/aastrika-elements.d.ts
CHANGED
|
@@ -1,21 +1,157 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The published type surface. This file IS the public API.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* It is hand-written rather than generated, because the bundle Angular emits is
|
|
5
|
+
* one file with no declarations and the three values a consumer touches are
|
|
6
|
+
* stable enough to state directly. Two rules follow from that:
|
|
7
|
+
*
|
|
8
|
+
* - Anything exported from src/elements/main.ts must be declared here, or a
|
|
9
|
+
* TypeScript consumer gets `any` for the one call the README mandates.
|
|
10
|
+
* - Anything declared here is a promise. Removing or renaming it is a
|
|
11
|
+
* breaking change; tests/lib/public-surface.test.ts fails on any drift.
|
|
12
|
+
*
|
|
13
|
+
* The tag declarations matter for a second reason. An Angular host embedding
|
|
14
|
+
* these adds CUSTOM_ELEMENTS_SCHEMA, which switches off template checking for
|
|
15
|
+
* every unknown tag in that component — not just ours. Declaring the tags gives
|
|
16
|
+
* it back for these three, so a typo in `aastrika-assessment` is still an error
|
|
17
|
+
* rather than a silently empty box. React and Vue hosts get completion from the
|
|
18
|
+
* same declarations.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** What a request failure tells the host. Stable across features. */
|
|
22
|
+
export interface AastrikaError {
|
|
23
|
+
/** Which element the failure came from. */
|
|
24
|
+
feature: 'content-studio' | 'assessment' | 'reports';
|
|
25
|
+
/** The sentence already shown to the user. */
|
|
26
|
+
message: string;
|
|
27
|
+
/** HTTP status. 0 means the request never left the browser — usually CORS. */
|
|
28
|
+
status?: number;
|
|
29
|
+
/** The service's stable code, when it sent one, e.g. `RENDER_TIMEOUT`. */
|
|
30
|
+
code?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Everything a host application tells this package. */
|
|
34
|
+
export interface AastrikaConfig {
|
|
35
|
+
/** Where the service is, no trailing slash. Empty string means same-origin. */
|
|
36
|
+
apiBase: string;
|
|
37
|
+
/** Headers proving the caller may use the service. Called before every request. */
|
|
38
|
+
getAuthHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
|
|
39
|
+
/** The username signed into YOUR application. Attribution, never verified. */
|
|
40
|
+
creator?: () => string | null;
|
|
41
|
+
/** Called whenever a request fails, so your monitoring hears about it. */
|
|
42
|
+
onError?: (error: AastrikaError) => void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Point the package at a service. Call once, before or after the elements are
|
|
47
|
+
* on the page; calling again replaces the configuration.
|
|
48
|
+
*/
|
|
49
|
+
export declare function configure(config: AastrikaConfig): void;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Resolves once the three tags are registered.
|
|
53
|
+
*
|
|
54
|
+
* Importing this module registers them as a side effect, so a host rarely needs
|
|
55
|
+
* this — it is here for code that must not run until the elements exist.
|
|
9
56
|
*/
|
|
57
|
+
export declare const ready: Promise<unknown>;
|
|
10
58
|
|
|
11
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Attributes are set in HTML (`default-language="kn"`), properties in JS
|
|
61
|
+
* (`el.defaultLanguage = 'kn'`), and events with addEventListener. Angular
|
|
62
|
+
* Elements maps one to the other, so a host uses whichever suits it.
|
|
63
|
+
*
|
|
64
|
+
* Every input is a STARTING value the user can still change, and every event
|
|
65
|
+
* is safe to ignore — an element with nothing bound behaves exactly as before.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
/** `<aastrika-content-studio>` — a document becomes a narrated training video. */
|
|
69
|
+
interface AastrikaContentStudioElement extends HTMLElement {
|
|
70
|
+
/**
|
|
71
|
+
* `'on'` shows the segment editor for an uploaded video. Defaults to `'off'`.
|
|
72
|
+
*
|
|
73
|
+
* Off by default because the editor loads per-segment thumbnails the service
|
|
74
|
+
* streams off local disk, which — unlike the finished video — have no
|
|
75
|
+
* presigned URL and so cannot load from another origin. Turn it on only for a
|
|
76
|
+
* same-origin host.
|
|
77
|
+
*/
|
|
78
|
+
editMode?: 'on' | 'off';
|
|
79
|
+
/** Language the form opens on, e.g. `'hi'`, `'en'`, `'kn'`, `'te'`. */
|
|
80
|
+
defaultLanguage?: string;
|
|
81
|
+
/** `'16:9'` or `'9:16'`. */
|
|
82
|
+
defaultAspectRatio?: string;
|
|
83
|
+
/** How much detail the video goes into, e.g. `'standard'`. */
|
|
84
|
+
defaultDepth?: string;
|
|
85
|
+
/** A voice id from `/v1/studio/list-voices`. */
|
|
86
|
+
defaultVoice?: string;
|
|
87
|
+
|
|
88
|
+
/** A plan came back. Free and repeatable, so this can fire more than once. */
|
|
89
|
+
addEventListener(
|
|
90
|
+
type: 'planReady',
|
|
91
|
+
listener: (e: CustomEvent<{ jobId: string; title: string; sceneCount: number; estimatedUsd: number | null }>) => void,
|
|
92
|
+
options?: boolean | AddEventListenerOptions,
|
|
93
|
+
): void;
|
|
94
|
+
/** The user committed to a render. This is the point money is spent. */
|
|
95
|
+
addEventListener(type: 'videoStarted', listener: (e: CustomEvent<{ jobId: string }>) => void,
|
|
96
|
+
options?: boolean | AddEventListenerOptions,
|
|
97
|
+
): void;
|
|
98
|
+
/** The video finished. `videoUrl` plays without an Authorization header. */
|
|
99
|
+
addEventListener(
|
|
100
|
+
type: 'videoReady',
|
|
101
|
+
listener: (e: CustomEvent<{ jobId: string; videoUrl: string }>) => void,
|
|
102
|
+
options?: boolean | AddEventListenerOptions,
|
|
103
|
+
): void;
|
|
104
|
+
addEventListener(
|
|
105
|
+
type: string,
|
|
106
|
+
listener: EventListenerOrEventListenerObject,
|
|
107
|
+
options?: boolean | AddEventListenerOptions,
|
|
108
|
+
): void;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** `<aastrika-assessment>` — source material becomes a validated MCQ set. */
|
|
112
|
+
interface AastrikaAssessmentElement extends HTMLElement {
|
|
113
|
+
/** Language the form opens on. */
|
|
114
|
+
defaultLanguage?: string;
|
|
115
|
+
/** How many questions to ask for. */
|
|
116
|
+
defaultQuestionCount?: number;
|
|
117
|
+
/** `'mixed'`, `'easy'`, `'medium'` or `'hard'`. */
|
|
118
|
+
defaultDifficulty?: string;
|
|
119
|
+
|
|
120
|
+
/** A validated question set came back. */
|
|
121
|
+
addEventListener(
|
|
122
|
+
type: 'assessmentReady',
|
|
123
|
+
listener: (e: CustomEvent<{ jobId: string; questionCount: number; language: string }>) => void,
|
|
124
|
+
options?: boolean | AddEventListenerOptions,
|
|
125
|
+
): void;
|
|
126
|
+
addEventListener(
|
|
127
|
+
type: string,
|
|
128
|
+
listener: EventListenerOrEventListenerObject,
|
|
129
|
+
options?: boolean | AddEventListenerOptions,
|
|
130
|
+
): void;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** `<aastrika-reports>` — usage and spend. Needs `contentAdmin` at the gateway. */
|
|
134
|
+
interface AastrikaReportsElement extends HTMLElement {
|
|
135
|
+
/** Opens filtered to one creator. The user can still clear it. */
|
|
136
|
+
creatorFilter?: string;
|
|
137
|
+
|
|
138
|
+
/** The figures are on screen. */
|
|
139
|
+
addEventListener(
|
|
140
|
+
type: 'reportLoaded',
|
|
141
|
+
listener: (e: CustomEvent<{ videos: number; assessments: number; users: number; spendUsd: number }>) => void,
|
|
142
|
+
options?: boolean | AddEventListenerOptions,
|
|
143
|
+
): void;
|
|
144
|
+
addEventListener(
|
|
145
|
+
type: string,
|
|
146
|
+
listener: EventListenerOrEventListenerObject,
|
|
147
|
+
options?: boolean | AddEventListenerOptions,
|
|
148
|
+
): void;
|
|
149
|
+
}
|
|
12
150
|
|
|
13
151
|
declare global {
|
|
14
152
|
interface HTMLElementTagNameMap {
|
|
15
|
-
'aastrika-content-studio':
|
|
16
|
-
'aastrika-assessment':
|
|
17
|
-
'aastrika-reports':
|
|
153
|
+
'aastrika-content-studio': AastrikaContentStudioElement;
|
|
154
|
+
'aastrika-assessment': AastrikaAssessmentElement;
|
|
155
|
+
'aastrika-reports': AastrikaReportsElement;
|
|
18
156
|
}
|
|
19
157
|
}
|
|
20
|
-
|
|
21
|
-
export {};
|