@voqalize/avatar 0.6.3 → 0.7.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 CHANGED
@@ -6,7 +6,7 @@ and shows the state of the call: listening, thinking, being interrupted.
6
6
 
7
7
  This package is the loader. The avatar itself (the characters, the renderer and
8
8
  everything that follows the call) is the Voqalize avatar runtime, which this
9
- package imports from `https://avatar.voqalize.com` when the first avatar mounts.
9
+ package imports from `https://cdn.voqalize.com` when the first avatar mounts.
10
10
  Each release of this package is pinned to the runtime it was released with, so
11
11
  upgrading the package is how you upgrade the avatar.
12
12
 
@@ -124,20 +124,41 @@ the `<div>` the avatar renders into.
124
124
 
125
125
  ## Content Security Policy
126
126
 
127
- If your page sets a Content-Security-Policy, add these sources:
127
+ If your page sets a Content-Security-Policy, add our host to these directives:
128
128
 
129
- - `script-src https://avatar.voqalize.com`, because the runtime is a module
130
- imported from there.
131
- - `connect-src https://avatar.voqalize.com blob:`, because the runtime fetches
132
- the character from there and decodes the character's textures from `blob:`
133
- URLs.
134
- - `img-src https://avatar.voqalize.com blob:`. The asset host serves the
135
- still photograph shown where a browser has no WebGL 2, as a call whose other
136
- side has turned their camera off; without it that tile shows an empty circle.
137
- `blob:` is for Safari before 17 and Firefox before 98, which decode the
138
- character's textures through an image element.
129
+ ```
130
+ script-src https://cdn.voqalize.com
131
+ connect-src https://cdn.voqalize.com
132
+ img-src https://cdn.voqalize.com
133
+ ```
139
134
 
140
- The runtime needs nothing else: no workers, no inline styles and no `eval`.
135
+ - `script-src`, because the runtime is a module imported from there.
136
+ - `connect-src`, because the runtime fetches the character from there.
137
+ - `img-src`, for the still photograph shown where a browser has no WebGL 2,
138
+ as a call whose other side has turned their camera off. Without it that
139
+ tile shows an empty circle; nothing else is affected.
140
+
141
+ The runtime needs nothing else: no `blob:`, no `data:`, no workers, no inline
142
+ styles and no `eval`. Safari before 17 and Firefox before 98 try one image from
143
+ a `blob:` URL first; the policy refuses it, the face draws all the same, and a
144
+ policy with a `report-to` gets one report from each such page. Your page's own call (its `connect-src` for the voice
145
+ service, its microphone permission) is not part of this list.
146
+
147
+ A policy applies to the page that sends it, so only the pages that mount an
148
+ avatar need these lines. To try them before you enforce them, send the policy
149
+ as `Content-Security-Policy-Report-Only`: the browser reports what it would
150
+ refuse and refuses nothing.
151
+
152
+ ### Upgrading from 0.6
153
+
154
+ Releases before 0.7 load from `https://avatar.voqalize.com` and asked for
155
+ `blob:` as well. That host serves the same files and stays up, and a policy
156
+ written for it keeps working with this release: the runtime is imported from
157
+ whichever name your policy allows (if your policy has a
158
+ `report-to`, expect one report for the name it refuses). Change your policy after you
159
+ upgrade the package, not before: a 0.6 package under the policy above is
160
+ refused its runtime. Once every page runs 0.7 or later you can drop
161
+ `avatar.voqalize.com` and `blob:` from your policy.
141
162
 
142
163
  ## Bundlers
143
164
 
@@ -149,4 +170,4 @@ avatars mount.
149
170
  ## Licence
150
171
 
151
172
  This package is MIT; see [LICENSE](./LICENSE). The runtime it loads is not open
152
- source. Its terms are at https://avatar.voqalize.com/LICENSE.
173
+ source. Its terms are at https://cdn.voqalize.com/LICENSE.
package/dist/index.d.ts CHANGED
@@ -15,16 +15,17 @@
15
15
  *
16
16
  * This package is the loader and nothing else. The avatar itself — the
17
17
  * characters, the renderer and everything that reads the call — is the
18
- * Voqalize avatar runtime, which this module imports from
19
- * `avatar.voqalize.com` at the version it was released with and which is
20
- * licensed separately. `createAvatar` returns at once; the face appears when
21
- * the runtime and the character have arrived.
18
+ * Voqalize avatar runtime, which this module imports from `cdn.voqalize.com`
19
+ * at the version it was released with and which is licensed separately.
20
+ * `createAvatar` returns at once; the face appears when the runtime and the
21
+ * character have arrived.
22
22
  *
23
- * A page with a Content-Security-Policy needs `https://avatar.voqalize.com` in
23
+ * A page with a Content-Security-Policy needs `https://cdn.voqalize.com` in
24
24
  * `script-src` (the runtime), `connect-src` (the character it fetches) and
25
- * `img-src` (the camera-off still, where there is no WebGL 2), and `blob:` in
26
- * `connect-src` (the character's textures are decoded from blob URLs;
27
- * `img-src` too on Safari before 17 and Firefox before 98).
25
+ * `img-src` (the camera-off still, where there is no WebGL 2), and nothing
26
+ * else. A policy written for a release before 0.7 names
27
+ * `avatar.voqalize.com`, the same host under its old name, and keeps working:
28
+ * a runtime the page refuses from one name is imported from the other.
28
29
  */
29
30
  import type { PipecatClient } from "@pipecat-ai/client-js";
30
31
  /** Amplitude, 0..2. `1` is as authored. */
package/dist/index.js CHANGED
@@ -15,23 +15,63 @@
15
15
  *
16
16
  * This package is the loader and nothing else. The avatar itself — the
17
17
  * characters, the renderer and everything that reads the call — is the
18
- * Voqalize avatar runtime, which this module imports from
19
- * `avatar.voqalize.com` at the version it was released with and which is
20
- * licensed separately. `createAvatar` returns at once; the face appears when
21
- * the runtime and the character have arrived.
18
+ * Voqalize avatar runtime, which this module imports from `cdn.voqalize.com`
19
+ * at the version it was released with and which is licensed separately.
20
+ * `createAvatar` returns at once; the face appears when the runtime and the
21
+ * character have arrived.
22
22
  *
23
- * A page with a Content-Security-Policy needs `https://avatar.voqalize.com` in
23
+ * A page with a Content-Security-Policy needs `https://cdn.voqalize.com` in
24
24
  * `script-src` (the runtime), `connect-src` (the character it fetches) and
25
- * `img-src` (the camera-off still, where there is no WebGL 2), and `blob:` in
26
- * `connect-src` (the character's textures are decoded from blob URLs;
27
- * `img-src` too on Safari before 17 and Firefox before 98).
25
+ * `img-src` (the camera-off still, where there is no WebGL 2), and nothing
26
+ * else. A policy written for a release before 0.7 names
27
+ * `avatar.voqalize.com`, the same host under its old name, and keeps working:
28
+ * a runtime the page refuses from one name is imported from the other.
28
29
  */
29
30
  import { PROTOCOL, RUNTIME_URL } from "./pin.js";
31
+ /**
32
+ * Each avatar host's other name: one bucket, served under both. The runtime
33
+ * keeps the same pairs for the files it fetches (`client/hosts.ts` in the
34
+ * private source; a test holds the copies equal).
35
+ */
36
+ const TWIN_HOSTS = {
37
+ "cdn.voqalize.com": "avatar.voqalize.com",
38
+ "avatar.voqalize.com": "cdn.voqalize.com",
39
+ "cdn.dev.voqalize.com": "avatar.dev.voqalize.com",
40
+ "avatar.dev.voqalize.com": "cdn.dev.voqalize.com",
41
+ };
42
+ /** The pinned runtime on the host's other name, or `null` where it has none. */
43
+ function aliasOf(url) {
44
+ try {
45
+ const parsed = new URL(url);
46
+ const other = TWIN_HOSTS[parsed.host];
47
+ if (!other)
48
+ return null;
49
+ parsed.host = other;
50
+ return parsed.href;
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
56
+ const importRuntime = (url) => import(/* @vite-ignore */ /* webpackIgnore: true */ url);
30
57
  let runtime;
31
58
  function load() {
32
59
  // One import per page, however many avatars mount; a failure is forgotten so
33
- // the next mount tries again rather than inheriting a dead promise.
34
- runtime ??= import(/* @vite-ignore */ /* webpackIgnore: true */ RUNTIME_URL).catch((error) => {
60
+ // the next mount tries again rather than inheriting a dead promise. A page
61
+ // whose policy names the host's other name — every policy written for a
62
+ // release before 0.7 — refuses the pinned URL, and gets the same file from
63
+ // the name it allows. Where that fails too, the first failure is the one
64
+ // reported: a runtime that threw while it ran says why, not the alias.
65
+ runtime ??= importRuntime(RUNTIME_URL)
66
+ .catch((error) => {
67
+ const alias = aliasOf(RUNTIME_URL);
68
+ if (!alias)
69
+ throw error;
70
+ return importRuntime(alias).catch(() => {
71
+ throw error;
72
+ });
73
+ })
74
+ .catch((error) => {
35
75
  runtime = undefined;
36
76
  throw error;
37
77
  });
package/dist/pin.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const RUNTIME_URL = "https://avatar.voqalize.com/runtime/runtime.TMD2YTCC.js";
1
+ export declare const RUNTIME_URL = "https://cdn.voqalize.com/runtime/runtime.5MKLUNW6.js";
2
2
  export declare const PROTOCOL = 1;
package/dist/pin.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Written by scripts/build-runtime.mjs — the runtime this shim is released with.
2
- export const RUNTIME_URL = "https://avatar.voqalize.com/runtime/runtime.TMD2YTCC.js";
2
+ export const RUNTIME_URL = "https://cdn.voqalize.com/runtime/runtime.5MKLUNW6.js";
3
3
  export const PROTOCOL = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voqalize/avatar",
3
- "version": "0.6.3",
3
+ "version": "0.7.0",
4
4
  "description": "A talking head for AI voice calls that embodies your pipecat client. This package loads the Voqalize avatar runtime.",
5
5
  "license": "MIT",
6
6
  "author": "Voqalize",