@telemetryos/root-sdk 1.4.4 → 1.5.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @telemetryos/root-sdk
2
2
 
3
+ ## 1.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Update cli enforce correct qs params
8
+
9
+ ## 1.5.0
10
+
11
+ ### Minor Changes
12
+
13
+ - Add message interceptors for root applications.
14
+
15
+ This allows root applications to listen for messages from their descendant
16
+ applications, and implement custom functionality those applications
17
+ can use, or allow for interop.
18
+
3
19
  ## 1.4.4
4
20
 
5
21
  ### Patch Changes
package/README.md CHANGED
@@ -182,6 +182,35 @@ iframe.src = url;
182
182
  document.body.appendChild(iframe);
183
183
  ```
184
184
 
185
+ ### Message Interceptors
186
+
187
+ Root applications can intercept messages from embedded sub-applications using message interceptors. This allows you to handle client messages before they bubble up to the parent window, enabling custom communication patterns:
188
+
189
+ ```javascript
190
+ import { applications } from '@telemetryos/root-sdk';
191
+
192
+ // Register an interceptor to provide color scheme to sub-applications
193
+ applications().bind('theme.getColorScheme', (data) => {
194
+ // Get the current color scheme from settings or state
195
+ const colors = getCurrentColorScheme();
196
+
197
+ // Return a bridge message that will be sent to handlers and child frames
198
+ return {
199
+ name: 'theme.colorScheme',
200
+ data: { primary: colors.primary, secondary: colors.secondary }
201
+ };
202
+ });
203
+
204
+ // The interceptor transforms client messages into bridge messages
205
+ // that are handled locally and forwarded to child applications
206
+ ```
207
+
208
+ Interceptors are useful for:
209
+ - **Theme Coordination** - Provide consistent color schemes and styling across embedded applications
210
+ - **State Synchronization** - Coordinate state changes across multiple embedded applications
211
+ - **Custom Routing** - Implement application-specific message routing logic
212
+ - **Data Transformation** - Normalize or transform message data before distribution
213
+
185
214
  ### Media Access
186
215
 
187
216
  Access media content uploaded to TelemetryOS:
@@ -1,4 +1,4 @@
1
- import { Client } from './client.js';
1
+ import { Client, MessageInterceptor } from './client.js';
2
2
  export type MountPoint = {
3
3
  [key: string]: any;
4
4
  path: string;
@@ -62,4 +62,35 @@ export declare class Applications {
62
62
  * ```
63
63
  */
64
64
  setDependencies(applicationSpecifiers: string[]): Promise<ApplicationsState>;
65
+ /**
66
+ * Registers a message interceptor for client messages from sub-applications.
67
+ *
68
+ * Interceptors allow a root application to handle messages from embedded child applications
69
+ * before they bubble up to the parent window. When an interceptor is registered, client messages
70
+ * with the specified name will be transformed into bridge messages that are handled locally
71
+ * and forwarded to child frames.
72
+ *
73
+ * This is useful for implementing custom communication patterns between root applications
74
+ * and their embedded sub-applications, such as coordinating theme changes, state
75
+ * synchronization, or custom routing logic.
76
+ *
77
+ * @param name The message name to intercept
78
+ * @param interceptor A function that receives the message data and returns a BridgeMessage
79
+ * @throws Error if an interceptor is already bound for the specified message name
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * import { applications } from '@telemetryos/root-sdk'
84
+ *
85
+ * // Intercept color scheme requests from sub-applications
86
+ * applications().bind('theme.getColorScheme', (data) => {
87
+ * const colors = getCurrentColorScheme()
88
+ * return {
89
+ * name: 'theme.colorScheme',
90
+ * data: { primary: colors.primary, secondary: colors.secondary }
91
+ * }
92
+ * })
93
+ * ```
94
+ */
95
+ bind(name: string, interceptor: MessageInterceptor): void;
65
96
  }
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
2
  import { bridgeMessageValidator } from './bridge-message-validator.js';
3
- export type Message = z.infer<typeof bridgeMessageValidator>;
3
+ type Message = z.infer<typeof bridgeMessageValidator>;
4
4
  export declare function formatBridgeMessage(data: Omit<Message, 'type'>): Message;
5
+ export {};
package/dist/bridge.d.ts CHANGED
@@ -5,12 +5,12 @@ import { bridgeMessageValidator } from './bridge-message-validator.js';
5
5
  * Defines the structure of a client message as defined in the
6
6
  * clientMessageValidator.
7
7
  */
8
- export type ClientMessage = z.infer<typeof clientMessageValidator>;
8
+ export type ClientMessage = Omit<z.infer<typeof clientMessageValidator>, 'type'>;
9
9
  /**
10
10
  * Defines the structure of a bridge message as defined in the
11
11
  * bridgeMessageValidator.
12
12
  */
13
- export type BridgeMessage = z.infer<typeof bridgeMessageValidator>;
13
+ export type BridgeMessage = Omit<z.infer<typeof bridgeMessageValidator>, 'type'>;
14
14
  /**
15
15
  * The Bridge class is provides a way for host applications to communicate with
16
16
  * TelemetryOS applications. It listens for window message events and sends
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
2
  import { clientMessageValidator } from './client-message-validator.js';
3
- export type Message = z.infer<typeof clientMessageValidator>;
3
+ type Message = z.infer<typeof clientMessageValidator>;
4
4
  export declare function formatClientMessage(data: Omit<Message, 'type'>): Message;
5
+ export {};
package/dist/client.d.ts CHANGED
@@ -7,6 +7,7 @@ import { Users } from './users.js';
7
7
  import { Proxy } from './proxy.js';
8
8
  import { Devices } from './devices.js';
9
9
  import { Weather } from './weather.js';
10
+ import { BridgeMessage } from './bridge.js';
10
11
  /**
11
12
  * The maximum time in milliseconds to wait for a response to a request call.
12
13
  *
@@ -33,6 +34,30 @@ export type SubscriptionResult<D = void> = {
33
34
  success: boolean;
34
35
  data: D;
35
36
  };
37
+ /**
38
+ * A function that intercepts client messages from sub-applications and transforms them
39
+ * into bridge messages.
40
+ *
41
+ * Message interceptors are registered using applications().bind() and allow root applications
42
+ * to handle messages from embedded child applications before they bubble up to the parent window.
43
+ * The interceptor receives the message data payload and must return a BridgeMessage object
44
+ * containing a name and data that will be forwarded to message handlers and child frames.
45
+ *
46
+ * @param data The data payload from the intercepted client message
47
+ * @returns A BridgeMessage object with name and data properties
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * const interceptor: MessageInterceptor = (data) => {
52
+ * const colors = getCurrentColorScheme()
53
+ * return {
54
+ * name: 'theme.colorScheme',
55
+ * data: { primary: colors.primary, secondary: colors.secondary }
56
+ * }
57
+ * }
58
+ * ```
59
+ */
60
+ export type MessageInterceptor = (data: any) => BridgeMessage;
36
61
  /**
37
62
  * Client is the core class that powers communication with the TelemetryOS platform.
38
63
  *
@@ -50,6 +75,7 @@ export declare class Client {
50
75
  _applicationName: string;
51
76
  _applicationInstance: string;
52
77
  _applicationSpecifier: string;
78
+ _messageInterceptors: Map<string, MessageInterceptor>;
53
79
  _onHandlers: Map<string, MessageHandler<any>[]>;
54
80
  _onceHandlers: Map<string, MessageHandler<any>[]>;
55
81
  _subscriptionNamesByHandler: Map<MessageHandler<any>, string>;
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("./index-JDXm3DEz.cjs"),F="1.4.4",T={version:F};class q{constructor(e){this._client=e}async getCurrent(){const e=await this._client.request("accounts.getCurrent",{});if(!e.success)throw new Error("Failed to fetch current account");return e.account}}class I{constructor(e){this._client=e}async getAllByMountPoint(e){return(await this._client.request("applications.getAllByMountPoint",{mountPoint:e})).applications}async getByName(e){return(await this._client.request("applications.getByName",{name:e})).application}async setDependencies(e){return await this._client.request("applications.setDependencies",{applicationSpecifiers:e})}}class P{constructor(e){this._client=e}async getInformation(){const e=await this._client.request("devices.getInformation",{});if(!e.success)throw new Error("Failed to get device information");return e.deviceInformation}}function $(o,e=console.error){o().catch(e)}class x{constructor(e){this._client=e}async getColorScheme(){return(await this._client.request("environment.getColorScheme",{})).colorScheme}subscribeColorScheme(e){$(async()=>{this._client.on("environment.colorSchemeChanged",e),e(await this.getColorScheme())})}unsubscribeColorScheme(e){this._client.off("environment.colorSchemeChanged",e)}}class E{constructor(e){this._client=e}async getAllFolders(){return(await this._client.request("mediaFolders.getAll",{})).folders}async getAllByFolderId(e){return(await this._client.request("media.getAllByFolderId",{folderId:e})).contents}async getAllByTag(e){return(await this._client.request("media.getAllByTag",{tagName:e})).contents}async getById(e){return(await this._client.request("media.getById",{id:e})).content}}class M{constructor(e){this._client=e}get application(){return new b("application","",this._client)}get instance(){return new b("instance",this._client.applicationSpecifier,this._client)}get device(){return new b("device",this._client.applicationSpecifier,this._client)}shared(e){return new b("shared",e,this._client)}}class b{constructor(e,t,n){this._kind=e,this._namespace=t,this._client=n}async set(e,t){return(await this._client.request("store.set",{kind:this._kind,namespace:this._namespace,key:e,value:t})).success}async get(e){return(await this._client.request("store.get",{kind:this._kind,namespace:this._namespace,key:e})).value}async subscribe(e,t){return(await this._client.subscribe("store.subscribe",{kind:this._kind,namespace:this._namespace,key:e},t)).success}async unsubscribe(e,t){return(await this._client.unsubscribe("store.unsubscribe",{kind:this._kind,namespace:this._namespace,key:e},t)).success}async delete(e){return(await this._client.request("store.delete",{kind:this._kind,namespace:this._namespace,key:e})).success}}class A{constructor(e){this._client=e}async getCurrent(){const e=await this._client.request("users.getCurrent",{});if(!e.success)throw new Error("Failed to fetch current user");return e.user}}class B{constructor(e){this._client=e}async getConditions(e){const t=await this._client.request("weather.getConditions",e);if(!t.success||!t.conditions)throw new Error(t.error||"Failed to fetch weather conditions");return t.conditions}async getDailyForecast(e){const t=await this._client.request("weather.getDailyForecast",e);if(!t.success||!t.forecast)throw new Error(t.error||"Failed to fetch daily forecast");return t.forecast}async getHourlyForecast(e){const t=await this._client.request("weather.getHourlyForecast",e);if(!t.success||!t.forecast)throw new Error(t.error||"Failed to fetch hourly forecast");return t.forecast}}function S(o){return{...o,type:"client"}}const R=y.z.object({type:y.z.literal("bridge"),name:y.z.string(),data:y.z.any()});class j{constructor(e){if(e._client._applicationSpecifier!=="rootSettingsNavigation")throw new Error("RootSettingsNavigation can only be used in the rootSettingsNavigation mount point");this._store=e}async setRootSettingsNavigation(e){var t;const n=this._store.shared("root-settings-navigation"),r=(t=await n.get("navigation"))!==null&&t!==void 0?t:{},s=this._store._client._applicationSpecifier;r[s]={applicationSpecifier:s,entries:e.entries},n.set("navigation",r)}async getRootSettingsNavigation(){var e;const n=(e=await this._store.shared("root-settings-navigation").get("navigation"))!==null&&e!==void 0?e:{},r=this._store._client._applicationSpecifier;return n[r]}async getAllRootSettingsNavigation(){var e;return(e=await this._store.shared("root-settings-navigation").get("navigation"))!==null&&e!==void 0?e:{}}}class D{constructor(e){this._client=e}async fetch(e,t){let n;typeof e=="string"?n=e:e instanceof URL?n=e.toString():(n=e.url,t||(t={method:e.method,headers:e.headers,body:e.body,credentials:e.credentials,cache:e.cache,redirect:e.redirect,referrer:e.referrer,integrity:e.integrity}));let r={};t!=null&&t.headers&&(t.headers instanceof Headers?t.headers.forEach((h,c)=>{r[c]=h}):Array.isArray(t.headers)?t.headers.forEach(([h,c])=>{r[h]=c}):r=t.headers);const s=await this._client.request("proxy.fetch",{url:n,method:(t==null?void 0:t.method)||"GET",headers:r,body:(t==null?void 0:t.body)||null});if(!s.success)throw new Error(`Proxy fetch failed: ${s.statusText}`);const l=new Headers(s.headers),u={status:s.status,statusText:s.statusText,headers:l};let a=null;return s.body!==null&&s.body!==void 0&&(typeof s.body=="string"||s.body instanceof ArrayBuffer?a=s.body:typeof s.body=="object"&&(a=JSON.stringify(s.body))),new Response(a,u)}}const g=1e3*30;class C{constructor(e){this._applicationName=e,this._applicationInstance="",this._applicationSpecifier="",this._onHandlers=new Map,this._onceHandlers=new Map,this._subscriptionNamesByHandler=new Map,this._subscriptionNamesBySubjectName=new Map}get accounts(){return new q(this)}get users(){return new A(this)}get store(){return new M(this)}get applications(){return new I(this)}get media(){return new E(this)}get proxy(){return new D(this)}get devices(){return new P(this)}get rootSettingsNavigation(){return new j(this.store)}get weather(){return new B(this)}get applicationName(){return this._applicationName}get applicationSpecifier(){return this._applicationSpecifier}get applicationInstance(){return this._applicationInstance}bind(){var e;const t=new URL(window.location.href),n=t.searchParams;this._applicationInstance=(e=n.get("telemetryApplicationId"))!==null&&e!==void 0?e:"";const r=n.get("applicationSpecifier");if(r)this._applicationSpecifier=r;else{const s=t.hostname.split(".");this._applicationSpecifier=s[0]||""}if(!this._applicationSpecifier||this._applicationSpecifier.length!==40)throw new Error(`Invalid applicationSpecifier: expected 40-character hash, got "${this._applicationSpecifier}"`);if(!this._applicationInstance)throw new Error("Missing telemetryApplicationId query parameter");this._windowMessageHandler=s=>{if(s.source===window||!s.data||!("type"in s.data)||s.data.type!=="client"&&s.data.type!=="bridge")return;if(s.data.type==="client"){window.parent.postMessage(s.data,"*");return}const l=R.safeParse(s.data);if(!l.success)return;const u=l.data,a=this._onHandlers.get(u.name),h=this._onceHandlers.get(u.name);if(a)for(const c of a)c(u.data);if(h){for(const c of h)c(u.data);this._onceHandlers.delete(u.name)}for(let c=0;c<window.frames.length;c+=1)window.frames[c].postMessage(s.data,"*")},window.addEventListener("message",this._windowMessageHandler)}unbind(){this._windowMessageHandler&&window.removeEventListener("message",this._windowMessageHandler)}send(e,t){const n=S({telemetrySdkVersion:_,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,applicationInstance:this._applicationInstance,name:e,data:t});window.parent.postMessage(n,"*")}request(e,t){const n=v(),r=S({telemetrySdkVersion:_,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,applicationInstance:this._applicationInstance,name:e,data:t,responseName:n});window.parent.postMessage(r,"*");let s=!1,l;const u=new Promise((h,c)=>{const d=new Error(`${e} message request with response name of ${n} timed out after ${g}`);setTimeout(()=>{s=!0,this.off(n,l),c(d)},g)}),a=new Promise(h=>{l=c=>{s||h(c)},this.once(n,h)});return Promise.race([u,a])}async subscribe(e,t,n){let r,s;typeof t=="function"?s=t:(r=t,s=n);const l=v(),u=v();let a=this._subscriptionNamesBySubjectName.get(e);a||(a=[],this._subscriptionNamesBySubjectName.set(e,a)),a.push(l),this._subscriptionNamesByHandler.set(s,l),this.on(l,s);const h=S({telemetrySdkVersion:_,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,applicationInstance:this._applicationInstance,name:e,data:r,responseName:u,subscriptionName:l});window.parent.postMessage(h,"*");let c=!1,d;const N=new Promise((w,f)=>{const m=new Error(`${e} subscribe request with subscription name of ${l} and response name of ${u} timed out after ${g}`);setTimeout(()=>{c=!0,this.off(u,d),f(m)},g)}),H=new Promise(w=>{d=f=>{c||w(f)},this.on(u,w)});return Promise.race([N,H])}async unsubscribe(e,t,n){let r,s;typeof t=="function"?s=t:(r=t,s=n);const l=v();let u=[];if(s){const a=this._subscriptionNamesByHandler.get(s);if(!a)return{success:!1};u=[a],this._subscriptionNamesByHandler.delete(s)}else if(!this._subscriptionNamesBySubjectName.get(e))return{success:!1};for await(const a of u){this.off(a,s);const h=S({telemetrySdkVersion:_,applicationInstance:this._applicationInstance,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,name:e,data:r,responseName:l,unsubscribeName:a});window.parent.postMessage(h,"*");let c=!1,d;const N=new Promise((f,m)=>{const k=new Error(`${e} unsubscribe request with unsubscribe name of ${a} and response name of ${l} timed out after ${g}`);setTimeout(()=>{c=!0,this.off(l,d),m(k)},g)}),H=new Promise(f=>{d=m=>{c||f(m)},this.once(l,f)});if(!(await Promise.race([N,H])).success)return{success:!1}}return{success:!0}}on(e,t){var n;const r=(n=this._onHandlers.get(e))!==null&&n!==void 0?n:[];r.length===0&&this._onHandlers.set(e,r),r.push(t)}once(e,t){var n;const r=(n=this._onceHandlers.get(e))!==null&&n!==void 0?n:[];r.length===0&&this._onceHandlers.set(e,r),r.push(t)}off(e,t){const n=this._onHandlers.get(e),r=this._onceHandlers.get(e);if(!(!n&&!r)){if(n){for(let s=0;s<n.length;s+=1)t&&n[s]!==t||(n.splice(s,1),s-=1);n.length===0&&this._onHandlers.delete(e)}if(r){for(let s=0;s<r.length;s+=1)t&&r[s]!==t||(r.splice(s,1),s-=1);r.length===0&&this._onceHandlers.delete(e)}}}}function v(){return Math.random().toString(36).slice(2,9)}const _=T.version;let i=null;function z(){return i}function L(o){i=new C(o),i.bind()}function U(){i==null||i.unbind(),i=null}function V(...o){return p(i),i.on(...o)}function O(...o){return p(i),i.once(...o)}function W(...o){return p(i),i.off(...o)}function G(...o){return p(i),i.send(...o)}function J(...o){return p(i),i.request(...o)}function K(...o){return p(i),i.subscribe(...o)}function Q(...o){return p(i),i.unsubscribe(...o)}function X(){return p(i),i.store}function Y(){return p(i),i.applications}function Z(){return p(i),i.media}function ee(){return p(i),i.accounts}function te(){return p(i),i.users}function se(){return p(i),i.devices}function ne(){return p(i),i.proxy}function ie(){return p(i),i.rootSettingsNavigation}function re(){return p(i),i.weather}function p(o){if(!o)throw new Error("SDK is not configured")}exports.Accounts=q;exports.Applications=I;exports.Client=C;exports.Devices=P;exports.Environment=x;exports.Media=E;exports.Store=M;exports.Users=A;exports.Weather=B;exports.accounts=ee;exports.applications=Y;exports.configure=L;exports.destroy=U;exports.devices=se;exports.globalClient=z;exports.media=Z;exports.off=W;exports.on=V;exports.once=O;exports.proxy=ne;exports.request=J;exports.rootSettingsNavigation=ie;exports.send=G;exports.store=X;exports.subscribe=K;exports.telemetrySdkVersion=_;exports.unsubscribe=Q;exports.users=te;exports.weather=re;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("./index-JDXm3DEz.cjs"),F="1.5.1",$={version:F};class H{constructor(e){this._client=e}async getCurrent(){const e=await this._client.request("accounts.getCurrent",{});if(!e.success)throw new Error("Failed to fetch current account");return e.account}}class q{constructor(e){this._client=e}async getAllByMountPoint(e){return(await this._client.request("applications.getAllByMountPoint",{mountPoint:e})).applications}async getByName(e){return(await this._client.request("applications.getByName",{name:e})).application}async setDependencies(e){return await this._client.request("applications.setDependencies",{applicationSpecifiers:e})}bind(e,t){if(this._client._messageInterceptors.has(e))throw new Error(`Interceptor already bound for message ${e}`);this._client._messageInterceptors.set(e,t)}}class E{constructor(e){this._client=e}async getInformation(){const e=await this._client.request("devices.getInformation",{});if(!e.success)throw new Error("Failed to get device information");return e.deviceInformation}}function x(a,e=console.error){a().catch(e)}class R{constructor(e){this._client=e}async getColorScheme(){return(await this._client.request("environment.getColorScheme",{})).colorScheme}subscribeColorScheme(e){x(async()=>{this._client.on("environment.colorSchemeChanged",e),e(await this.getColorScheme())})}unsubscribeColorScheme(e){this._client.off("environment.colorSchemeChanged",e)}}class M{constructor(e){this._client=e}async getAllFolders(){return(await this._client.request("mediaFolders.getAll",{})).folders}async getAllByFolderId(e){return(await this._client.request("media.getAllByFolderId",{folderId:e})).contents}async getAllByTag(e){return(await this._client.request("media.getAllByTag",{tagName:e})).contents}async getById(e){return(await this._client.request("media.getById",{id:e})).content}}class P{constructor(e){this._client=e}async fetch(e,t){var s;let o;typeof e=="string"?o=e:e instanceof URL?o=e.toString():(o=e.url,t||(t={method:e.method,headers:e.headers,body:e.body,credentials:e.credentials,cache:e.cache,redirect:e.redirect,referrer:e.referrer,integrity:e.integrity}));let r={};t!=null&&t.headers&&(t.headers instanceof Headers?t.headers.forEach((u,p)=>{r[p]=u}):Array.isArray(t.headers)?t.headers.forEach(([u,p])=>{r[u]=p}):r=t.headers);const n=await this._client.request("proxy.fetch",{url:o,method:(t==null?void 0:t.method)||"GET",headers:r,body:(s=t==null?void 0:t.body)!==null&&s!==void 0?s:null});if(!n.success)throw new TypeError(n.errorMessage,{cause:n.errorCause?Error(n.errorCause):void 0});const l=new Headers(n.headers),c={status:n.status,statusText:n.statusText,headers:l};let h=null;if(n.body!==null&&n.body!==void 0)if(n.bodyType==="binary"){const u=atob(n.body),p=new Uint8Array(u.length);for(let f=0;f<u.length;f++)p[f]=u.charCodeAt(f);h=p}else n.bodyType==="text"?h=n.body:n.bodyType==="json"&&(h=JSON.stringify(n.body));return new Response(h,c)}}class C{constructor(e){this._client=e}get application(){return new S("application","",this._client)}get instance(){return new S("instance",this._client.applicationInstance,this._client)}get device(){return new S("device",this._client.applicationInstance,this._client)}shared(e){return new S("shared",e,this._client)}}class S{constructor(e,t,s){this._kind=e,this._namespace=t,this._client=s}async set(e,t){return(await this._client.request("store.set",{kind:this._kind,namespace:this._namespace,key:e,value:t})).success}async get(e){return(await this._client.request("store.get",{kind:this._kind,namespace:this._namespace,key:e})).value}async subscribe(e,t){return(await this._client.subscribe("store.subscribe",{kind:this._kind,namespace:this._namespace,key:e},t)).success}async unsubscribe(e,t){return(await this._client.unsubscribe("store.unsubscribe",{kind:this._kind,namespace:this._namespace,key:e},t)).success}async delete(e){return(await this._client.request("store.delete",{kind:this._kind,namespace:this._namespace,key:e})).success}}class A{constructor(e){this._client=e}async getCurrent(){const e=await this._client.request("users.getCurrent",{});if(!e.success)throw new Error("Failed to fetch current user");return e.user}}class B{constructor(e){this._client=e}async getConditions(e){const t=await this._client.request("weather.getConditions",e);if(!t.success||!t.conditions)throw new Error(t.error||"Failed to fetch weather conditions");return t.conditions}async getDailyForecast(e){const t=await this._client.request("weather.getDailyForecast",e);if(!t.success||!t.forecast)throw new Error(t.error||"Failed to fetch daily forecast");return t.forecast}async getHourlyForecast(e){const t=await this._client.request("weather.getHourlyForecast",e);if(!t.success||!t.forecast)throw new Error(t.error||"Failed to fetch hourly forecast");return t.forecast}}function v(a){return{...a,type:"client"}}const j=b.z.object({type:b.z.literal("bridge"),name:b.z.string(),data:b.z.any()});class D{constructor(e){if(e._client._applicationSpecifier!=="rootSettingsNavigation")throw new Error("RootSettingsNavigation can only be used in the rootSettingsNavigation mount point");this._store=e}async setRootSettingsNavigation(e){var t;const s=this._store.shared("root-settings-navigation"),o=(t=await s.get("navigation"))!==null&&t!==void 0?t:{},r=this._store._client._applicationSpecifier;o[r]={applicationSpecifier:r,entries:e.entries},s.set("navigation",o)}async getRootSettingsNavigation(){var e;const s=(e=await this._store.shared("root-settings-navigation").get("navigation"))!==null&&e!==void 0?e:{},o=this._store._client._applicationSpecifier;return s[o]}async getAllRootSettingsNavigation(){var e;return(e=await this._store.shared("root-settings-navigation").get("navigation"))!==null&&e!==void 0?e:{}}}const _=1e3*30;class T{constructor(e){this._applicationName=e,this._applicationInstance="",this._applicationSpecifier="",this._messageInterceptors=new Map,this._onHandlers=new Map,this._onceHandlers=new Map,this._subscriptionNamesByHandler=new Map,this._subscriptionNamesBySubjectName=new Map}get accounts(){return new H(this)}get users(){return new A(this)}get store(){return new C(this)}get applications(){return new q(this)}get media(){return new M(this)}get proxy(){return new P(this)}get devices(){return new E(this)}get rootSettingsNavigation(){return new D(this.store)}get weather(){return new B(this)}get applicationName(){return this._applicationName}get applicationSpecifier(){return this._applicationSpecifier}get applicationInstance(){return this._applicationInstance}bind(){var e,t,s;const o=new URL(window.location.href),r=o.searchParams;if(this._applicationInstance=(e=r.get("applicationInstance"))!==null&&e!==void 0?e:"",!this._applicationInstance)throw new Error("Missing applicationInstance query parameter");if(this._applicationSpecifier=(t=r.get("applicationSpecifier"))!==null&&t!==void 0?t:"",!this._applicationSpecifier){const n=o.hostname.split(".");this._applicationSpecifier=(s=n[0])!==null&&s!==void 0?s:""}if(!this._applicationSpecifier||this._applicationSpecifier.length!==40)throw new Error(`Invalid applicationSpecifier: expected 40-character hash, got "${this._applicationSpecifier}"`);this._windowMessageHandler=n=>{if(n.source===window||!n.data||!("type"in n.data)||n.data.type!=="client"&&n.data.type!=="bridge")return;let l;if(n.data.type==="client"){const c=this._messageInterceptors.get(n.data.name);if(!c){window.parent.postMessage(n.data,"*");return}l={...c(n.data.data),type:"bridge"}}if(!l){const c=j.safeParse(n.data);if(!c.success)return;l=c.data;const h=this._onHandlers.get(l.name),u=this._onceHandlers.get(l.name);if(h)for(const p of h)p(l.data);if(u){for(const p of u)p(l.data);this._onceHandlers.delete(l.name)}}for(let c=0;c<window.frames.length;c+=1)window.frames[c].postMessage(l,"*")},window.addEventListener("message",this._windowMessageHandler)}unbind(){this._windowMessageHandler&&window.removeEventListener("message",this._windowMessageHandler)}send(e,t){const s=v({telemetrySdkVersion:w,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,applicationInstance:this._applicationInstance,name:e,data:t});window.parent.postMessage(s,"*")}request(e,t){const s=N(),o=v({telemetrySdkVersion:w,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,applicationInstance:this._applicationInstance,name:e,data:t,responseName:s});window.parent.postMessage(o,"*");let r=!1,n;const l=new Promise((h,u)=>{const p=new Error(`${e} message request with response name of ${s} timed out after ${_}`);setTimeout(()=>{r=!0,this.off(s,n),u(p)},_)}),c=new Promise(h=>{n=u=>{r||h(u)},this.once(s,h)});return Promise.race([l,c])}async subscribe(e,t,s){let o,r;typeof t=="function"?r=t:(o=t,r=s);const n=N(),l=N();let c=this._subscriptionNamesBySubjectName.get(e);c||(c=[],this._subscriptionNamesBySubjectName.set(e,c)),c.push(n),this._subscriptionNamesByHandler.set(r,n),this.on(n,r);const h=v({telemetrySdkVersion:w,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,applicationInstance:this._applicationInstance,name:e,data:o,responseName:l,subscriptionName:n});window.parent.postMessage(h,"*");let u=!1,p;const f=new Promise((y,g)=>{const m=new Error(`${e} subscribe request with subscription name of ${n} and response name of ${l} timed out after ${_}`);setTimeout(()=>{u=!0,this.off(l,p),g(m)},_)}),I=new Promise(y=>{p=g=>{u||y(g)},this.on(l,y)});return Promise.race([f,I])}async unsubscribe(e,t,s){let o,r;typeof t=="function"?r=t:(o=t,r=s);const n=N();let l=[];if(r){const c=this._subscriptionNamesByHandler.get(r);if(!c)return{success:!1};l=[c],this._subscriptionNamesByHandler.delete(r)}else if(!this._subscriptionNamesBySubjectName.get(e))return{success:!1};for await(const c of l){this.off(c,r);const h=v({telemetrySdkVersion:w,applicationInstance:this._applicationInstance,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,name:e,data:o,responseName:n,unsubscribeName:c});window.parent.postMessage(h,"*");let u=!1,p;const f=new Promise((g,m)=>{const k=new Error(`${e} unsubscribe request with unsubscribe name of ${c} and response name of ${n} timed out after ${_}`);setTimeout(()=>{u=!0,this.off(n,p),m(k)},_)}),I=new Promise(g=>{p=m=>{u||g(m)},this.once(n,g)});if(!(await Promise.race([f,I])).success)return{success:!1}}return{success:!0}}on(e,t){var s;const o=(s=this._onHandlers.get(e))!==null&&s!==void 0?s:[];o.length===0&&this._onHandlers.set(e,o),o.push(t)}once(e,t){var s;const o=(s=this._onceHandlers.get(e))!==null&&s!==void 0?s:[];o.length===0&&this._onceHandlers.set(e,o),o.push(t)}off(e,t){const s=this._onHandlers.get(e),o=this._onceHandlers.get(e);if(!(!s&&!o)){if(s){for(let r=0;r<s.length;r+=1)t&&s[r]!==t||(s.splice(r,1),r-=1);s.length===0&&this._onHandlers.delete(e)}if(o){for(let r=0;r<o.length;r+=1)t&&o[r]!==t||(o.splice(r,1),r-=1);o.length===0&&this._onceHandlers.delete(e)}}}}function N(){return Math.random().toString(36).slice(2,9)}const w=$.version;let i=null;function U(){return i}function z(a){i=new T(a),i.bind()}function L(){i==null||i.unbind(),i=null}function V(...a){return d(i),i.on(...a)}function O(...a){return d(i),i.once(...a)}function W(...a){return d(i),i.off(...a)}function G(...a){return d(i),i.send(...a)}function J(...a){return d(i),i.request(...a)}function K(...a){return d(i),i.subscribe(...a)}function Q(...a){return d(i),i.unsubscribe(...a)}function X(){return d(i),i.store}function Y(){return d(i),i.applications}function Z(){return d(i),i.media}function ee(){return d(i),i.accounts}function te(){return d(i),i.users}function se(){return d(i),i.devices}function ne(){return d(i),i.proxy}function ie(){return d(i),i.rootSettingsNavigation}function re(){return d(i),i.weather}function d(a){if(!a)throw new Error("SDK is not configured")}exports.Accounts=H;exports.Applications=q;exports.Client=T;exports.Devices=E;exports.Environment=R;exports.Media=M;exports.Proxy=P;exports.Store=C;exports.Users=A;exports.Weather=B;exports.accounts=ee;exports.applications=Y;exports.configure=z;exports.destroy=L;exports.devices=se;exports.globalClient=U;exports.media=Z;exports.off=W;exports.on=V;exports.once=O;exports.proxy=ne;exports.request=J;exports.rootSettingsNavigation=ie;exports.send=G;exports.store=X;exports.subscribe=K;exports.telemetrySdkVersion=w;exports.unsubscribe=Q;exports.users=te;exports.weather=re;
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { Applications } from './applications.js';
3
3
  export { Devices } from './devices.js';
4
4
  export { Environment } from './environment.js';
5
5
  export { Media } from './media.js';
6
+ export { Proxy } from './proxy.js';
6
7
  export { Store } from './store.js';
7
8
  export { Users } from './users.js';
8
9
  export { Weather } from './weather.js';
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { z as w } from "./index-B98VDFRY.js";
2
- const I = "1.4.4", P = {
3
- version: I
1
+ import { z as y } from "./index-B98VDFRY.js";
2
+ const q = "1.5.1", E = {
3
+ version: q
4
4
  };
5
- class E {
5
+ class M {
6
6
  constructor(e) {
7
7
  this._client = e;
8
8
  }
@@ -21,7 +21,7 @@ class E {
21
21
  return e.account;
22
22
  }
23
23
  }
24
- class M {
24
+ class P {
25
25
  constructor(e) {
26
26
  this._client = e;
27
27
  }
@@ -82,8 +82,43 @@ class M {
82
82
  applicationSpecifiers: e
83
83
  });
84
84
  }
85
+ /**
86
+ * Registers a message interceptor for client messages from sub-applications.
87
+ *
88
+ * Interceptors allow a root application to handle messages from embedded child applications
89
+ * before they bubble up to the parent window. When an interceptor is registered, client messages
90
+ * with the specified name will be transformed into bridge messages that are handled locally
91
+ * and forwarded to child frames.
92
+ *
93
+ * This is useful for implementing custom communication patterns between root applications
94
+ * and their embedded sub-applications, such as coordinating theme changes, state
95
+ * synchronization, or custom routing logic.
96
+ *
97
+ * @param name The message name to intercept
98
+ * @param interceptor A function that receives the message data and returns a BridgeMessage
99
+ * @throws Error if an interceptor is already bound for the specified message name
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * import { applications } from '@telemetryos/root-sdk'
104
+ *
105
+ * // Intercept color scheme requests from sub-applications
106
+ * applications().bind('theme.getColorScheme', (data) => {
107
+ * const colors = getCurrentColorScheme()
108
+ * return {
109
+ * name: 'theme.colorScheme',
110
+ * data: { primary: colors.primary, secondary: colors.secondary }
111
+ * }
112
+ * })
113
+ * ```
114
+ */
115
+ bind(e, t) {
116
+ if (this._client._messageInterceptors.has(e))
117
+ throw new Error(`Interceptor already bound for message ${e}`);
118
+ this._client._messageInterceptors.set(e, t);
119
+ }
85
120
  }
86
- class A {
121
+ class C {
87
122
  constructor(e) {
88
123
  this._client = e;
89
124
  }
@@ -107,8 +142,8 @@ class A {
107
142
  return e.deviceInformation;
108
143
  }
109
144
  }
110
- function B(o, e = console.error) {
111
- o().catch(e);
145
+ function A(a, e = console.error) {
146
+ a().catch(e);
112
147
  }
113
148
  class L {
114
149
  constructor(e) {
@@ -118,7 +153,7 @@ class L {
118
153
  return (await this._client.request("environment.getColorScheme", {})).colorScheme;
119
154
  }
120
155
  subscribeColorScheme(e) {
121
- B(async () => {
156
+ A(async () => {
122
157
  this._client.on("environment.colorSchemeChanged", e), e(await this.getColorScheme());
123
158
  });
124
159
  }
@@ -126,7 +161,7 @@ class L {
126
161
  this._client.off("environment.colorSchemeChanged", e);
127
162
  }
128
163
  }
129
- class C {
164
+ class B {
130
165
  constructor(e) {
131
166
  this._client = e;
132
167
  }
@@ -172,6 +207,55 @@ class C {
172
207
  })).content;
173
208
  }
174
209
  }
210
+ class T {
211
+ constructor(e) {
212
+ this._client = e;
213
+ }
214
+ async fetch(e, t) {
215
+ var s;
216
+ let o;
217
+ typeof e == "string" ? o = e : e instanceof URL ? o = e.toString() : (o = e.url, t || (t = {
218
+ method: e.method,
219
+ headers: e.headers,
220
+ body: e.body,
221
+ credentials: e.credentials,
222
+ cache: e.cache,
223
+ redirect: e.redirect,
224
+ referrer: e.referrer,
225
+ integrity: e.integrity
226
+ }));
227
+ let r = {};
228
+ t != null && t.headers && (t.headers instanceof Headers ? t.headers.forEach((u, p) => {
229
+ r[p] = u;
230
+ }) : Array.isArray(t.headers) ? t.headers.forEach(([u, p]) => {
231
+ r[u] = p;
232
+ }) : r = t.headers);
233
+ const n = await this._client.request("proxy.fetch", {
234
+ url: o,
235
+ method: (t == null ? void 0 : t.method) || "GET",
236
+ headers: r,
237
+ body: (s = t == null ? void 0 : t.body) !== null && s !== void 0 ? s : null
238
+ });
239
+ if (!n.success)
240
+ throw new TypeError(n.errorMessage, {
241
+ cause: n.errorCause ? Error(n.errorCause) : void 0
242
+ });
243
+ const l = new Headers(n.headers), c = {
244
+ status: n.status,
245
+ statusText: n.statusText,
246
+ headers: l
247
+ };
248
+ let h = null;
249
+ if (n.body !== null && n.body !== void 0)
250
+ if (n.bodyType === "binary") {
251
+ const u = atob(n.body), p = new Uint8Array(u.length);
252
+ for (let f = 0; f < u.length; f++)
253
+ p[f] = u.charCodeAt(f);
254
+ h = p;
255
+ } else n.bodyType === "text" ? h = n.body : n.bodyType === "json" && (h = JSON.stringify(n.body));
256
+ return new Response(h, c);
257
+ }
258
+ }
175
259
  class F {
176
260
  constructor(e) {
177
261
  this._client = e;
@@ -186,7 +270,7 @@ class F {
186
270
  * @returns A StoreSlice instance for the application scope
187
271
  */
188
272
  get application() {
189
- return new y("application", "", this._client);
273
+ return new b("application", "", this._client);
190
274
  }
191
275
  /**
192
276
  * Provides access to the instance store scope.
@@ -200,7 +284,7 @@ class F {
200
284
  * @returns A StoreSlice instance for the instance scope
201
285
  */
202
286
  get instance() {
203
- return new y("instance", this._client.applicationSpecifier, this._client);
287
+ return new b("instance", this._client.applicationInstance, this._client);
204
288
  }
205
289
  /**
206
290
  * Provides access to the device store scope.
@@ -215,7 +299,7 @@ class F {
215
299
  * @returns A StoreSlice instance for the device scope
216
300
  */
217
301
  get device() {
218
- return new y("device", this._client.applicationSpecifier, this._client);
302
+ return new b("device", this._client.applicationInstance, this._client);
219
303
  }
220
304
  /**
221
305
  * Provides access to the shared store scope with a specified namespace.
@@ -231,12 +315,12 @@ class F {
231
315
  * @returns A StoreSlice instance for the specified shared namespace
232
316
  */
233
317
  shared(e) {
234
- return new y("shared", e, this._client);
318
+ return new b("shared", e, this._client);
235
319
  }
236
320
  }
237
- class y {
238
- constructor(e, t, n) {
239
- this._kind = e, this._namespace = t, this._client = n;
321
+ class b {
322
+ constructor(e, t, s) {
323
+ this._kind = e, this._namespace = t, this._client = s;
240
324
  }
241
325
  /**
242
326
  * Saves a value in the store.
@@ -351,7 +435,7 @@ class k {
351
435
  return e.user;
352
436
  }
353
437
  }
354
- class T {
438
+ class $ {
355
439
  constructor(e) {
356
440
  this._client = e;
357
441
  }
@@ -427,15 +511,15 @@ class T {
427
511
  return t.forecast;
428
512
  }
429
513
  }
430
- function b(o) {
431
- return { ...o, type: "client" };
514
+ function S(a) {
515
+ return { ...a, type: "client" };
432
516
  }
433
- const $ = w.object({
434
- type: w.literal("bridge"),
435
- name: w.string(),
436
- data: w.any()
517
+ const x = y.object({
518
+ type: y.literal("bridge"),
519
+ name: y.string(),
520
+ data: y.any()
437
521
  });
438
- class x {
522
+ class R {
439
523
  /**
440
524
  * Creates a new RootSettingsNavigation API instance.
441
525
  *
@@ -459,11 +543,11 @@ class x {
459
543
  */
460
544
  async setRootSettingsNavigation(e) {
461
545
  var t;
462
- const n = this._store.shared("root-settings-navigation"), r = (t = await n.get("navigation")) !== null && t !== void 0 ? t : {}, s = this._store._client._applicationSpecifier;
463
- r[s] = {
464
- applicationSpecifier: s,
546
+ const s = this._store.shared("root-settings-navigation"), o = (t = await s.get("navigation")) !== null && t !== void 0 ? t : {}, r = this._store._client._applicationSpecifier;
547
+ o[r] = {
548
+ applicationSpecifier: r,
465
549
  entries: e.entries
466
- }, n.set("navigation", r);
550
+ }, s.set("navigation", o);
467
551
  }
468
552
  /**
469
553
  * Retrieves the current navigation entries for this root application.
@@ -475,8 +559,8 @@ class x {
475
559
  */
476
560
  async getRootSettingsNavigation() {
477
561
  var e;
478
- const n = (e = await this._store.shared("root-settings-navigation").get("navigation")) !== null && e !== void 0 ? e : {}, r = this._store._client._applicationSpecifier;
479
- return n[r];
562
+ const s = (e = await this._store.shared("root-settings-navigation").get("navigation")) !== null && e !== void 0 ? e : {}, o = this._store._client._applicationSpecifier;
563
+ return s[o];
480
564
  }
481
565
  /**
482
566
  * Retrieves the navigation entries for all root applications.
@@ -492,46 +576,7 @@ class x {
492
576
  return (e = await this._store.shared("root-settings-navigation").get("navigation")) !== null && e !== void 0 ? e : {};
493
577
  }
494
578
  }
495
- class R {
496
- constructor(e) {
497
- this._client = e;
498
- }
499
- async fetch(e, t) {
500
- let n;
501
- typeof e == "string" ? n = e : e instanceof URL ? n = e.toString() : (n = e.url, t || (t = {
502
- method: e.method,
503
- headers: e.headers,
504
- body: e.body,
505
- credentials: e.credentials,
506
- cache: e.cache,
507
- redirect: e.redirect,
508
- referrer: e.referrer,
509
- integrity: e.integrity
510
- }));
511
- let r = {};
512
- t != null && t.headers && (t.headers instanceof Headers ? t.headers.forEach((h, c) => {
513
- r[c] = h;
514
- }) : Array.isArray(t.headers) ? t.headers.forEach(([h, c]) => {
515
- r[h] = c;
516
- }) : r = t.headers);
517
- const s = await this._client.request("proxy.fetch", {
518
- url: n,
519
- method: (t == null ? void 0 : t.method) || "GET",
520
- headers: r,
521
- body: (t == null ? void 0 : t.body) || null
522
- });
523
- if (!s.success)
524
- throw new Error(`Proxy fetch failed: ${s.statusText}`);
525
- const l = new Headers(s.headers), u = {
526
- status: s.status,
527
- statusText: s.statusText,
528
- headers: l
529
- };
530
- let a = null;
531
- return s.body !== null && s.body !== void 0 && (typeof s.body == "string" || s.body instanceof ArrayBuffer ? a = s.body : typeof s.body == "object" && (a = JSON.stringify(s.body))), new Response(a, u);
532
- }
533
- }
534
- const g = 1e3 * 30;
579
+ const _ = 1e3 * 30;
535
580
  class j {
536
581
  /**
537
582
  * Creates a new Client instance for communicating with the TelemetryOS platform.
@@ -544,7 +589,7 @@ class j {
544
589
  * in your application's telemetry.config.json file
545
590
  */
546
591
  constructor(e) {
547
- this._applicationName = e, this._applicationInstance = "", this._applicationSpecifier = "", this._onHandlers = /* @__PURE__ */ new Map(), this._onceHandlers = /* @__PURE__ */ new Map(), this._subscriptionNamesByHandler = /* @__PURE__ */ new Map(), this._subscriptionNamesBySubjectName = /* @__PURE__ */ new Map();
592
+ this._applicationName = e, this._applicationInstance = "", this._applicationSpecifier = "", this._messageInterceptors = /* @__PURE__ */ new Map(), this._onHandlers = /* @__PURE__ */ new Map(), this._onceHandlers = /* @__PURE__ */ new Map(), this._subscriptionNamesByHandler = /* @__PURE__ */ new Map(), this._subscriptionNamesBySubjectName = /* @__PURE__ */ new Map();
548
593
  }
549
594
  /**
550
595
  * Provides access to the accounts API for retrieving TelemetryOS account information.
@@ -558,7 +603,7 @@ class j {
558
603
  * @returns An Accounts instance bound to this client
559
604
  */
560
605
  get accounts() {
561
- return new E(this);
606
+ return new M(this);
562
607
  }
563
608
  /**
564
609
  * Provides access to the users API for retrieving TelemetryOS user information.
@@ -600,7 +645,7 @@ class j {
600
645
  * @returns An Applications instance bound to this client
601
646
  */
602
647
  get applications() {
603
- return new M(this);
648
+ return new P(this);
604
649
  }
605
650
  /**
606
651
  * Provides access to the media API for working with content hosted on the TelemetryOS platform.
@@ -615,7 +660,7 @@ class j {
615
660
  * @returns A Media instance bound to this client
616
661
  */
617
662
  get media() {
618
- return new C(this);
663
+ return new B(this);
619
664
  }
620
665
  /**
621
666
  * Provides access to the proxy API for fetching third-party content through the TelemetryOS API.
@@ -629,7 +674,7 @@ class j {
629
674
  * @returns A Proxy instance bound to this client
630
675
  */
631
676
  get proxy() {
632
- return new R(this);
677
+ return new T(this);
633
678
  }
634
679
  /**
635
680
  * Provides access to the devices API for interacting with the current device.
@@ -644,7 +689,7 @@ class j {
644
689
  * @returns A Devices instance bound to this client
645
690
  */
646
691
  get devices() {
647
- return new A(this);
692
+ return new C(this);
648
693
  }
649
694
  /**
650
695
  * Provides access to the root settings navigation API for TelemetryOS administration UI integration.
@@ -662,7 +707,7 @@ class j {
662
707
  * @throws {Error} If used by an application not mounted at the 'rootSettingsNavigation' mount point
663
708
  */
664
709
  get rootSettingsNavigation() {
665
- return new x(this.store);
710
+ return new R(this.store);
666
711
  }
667
712
  /**
668
713
  * Provides access to the weather API for retrieving weather data.
@@ -676,7 +721,7 @@ class j {
676
721
  * @returns A Weather instance bound to this client
677
722
  */
678
723
  get weather() {
679
- return new T(this);
724
+ return new $(this);
680
725
  }
681
726
  get applicationName() {
682
727
  return this._applicationName;
@@ -703,41 +748,45 @@ class j {
703
748
  * of creating and binding their own Client instances.
704
749
  */
705
750
  bind() {
706
- var e;
707
- const t = new URL(window.location.href), n = t.searchParams;
708
- this._applicationInstance = (e = n.get("telemetryApplicationId")) !== null && e !== void 0 ? e : "";
709
- const r = n.get("applicationSpecifier");
710
- if (r)
711
- this._applicationSpecifier = r;
712
- else {
713
- const s = t.hostname.split(".");
714
- this._applicationSpecifier = s[0] || "";
751
+ var e, t, s;
752
+ const o = new URL(window.location.href), r = o.searchParams;
753
+ if (this._applicationInstance = (e = r.get("applicationInstance")) !== null && e !== void 0 ? e : "", !this._applicationInstance)
754
+ throw new Error("Missing applicationInstance query parameter");
755
+ if (this._applicationSpecifier = (t = r.get("applicationSpecifier")) !== null && t !== void 0 ? t : "", !this._applicationSpecifier) {
756
+ const n = o.hostname.split(".");
757
+ this._applicationSpecifier = (s = n[0]) !== null && s !== void 0 ? s : "";
715
758
  }
716
759
  if (!this._applicationSpecifier || this._applicationSpecifier.length !== 40)
717
760
  throw new Error(`Invalid applicationSpecifier: expected 40-character hash, got "${this._applicationSpecifier}"`);
718
- if (!this._applicationInstance)
719
- throw new Error("Missing telemetryApplicationId query parameter");
720
- this._windowMessageHandler = (s) => {
721
- if (s.source === window || !s.data || !("type" in s.data) || s.data.type !== "client" && s.data.type !== "bridge")
722
- return;
723
- if (s.data.type === "client") {
724
- window.parent.postMessage(s.data, "*");
761
+ this._windowMessageHandler = (n) => {
762
+ if (n.source === window || !n.data || !("type" in n.data) || n.data.type !== "client" && n.data.type !== "bridge")
725
763
  return;
764
+ let l;
765
+ if (n.data.type === "client") {
766
+ const c = this._messageInterceptors.get(n.data.name);
767
+ if (!c) {
768
+ window.parent.postMessage(n.data, "*");
769
+ return;
770
+ }
771
+ l = { ...c(n.data.data), type: "bridge" };
726
772
  }
727
- const l = $.safeParse(s.data);
728
- if (!l.success)
729
- return;
730
- const u = l.data, a = this._onHandlers.get(u.name), h = this._onceHandlers.get(u.name);
731
- if (a)
732
- for (const c of a)
733
- c(u.data);
734
- if (h) {
735
- for (const c of h)
736
- c(u.data);
737
- this._onceHandlers.delete(u.name);
773
+ if (!l) {
774
+ const c = x.safeParse(n.data);
775
+ if (!c.success)
776
+ return;
777
+ l = c.data;
778
+ const h = this._onHandlers.get(l.name), u = this._onceHandlers.get(l.name);
779
+ if (h)
780
+ for (const p of h)
781
+ p(l.data);
782
+ if (u) {
783
+ for (const p of u)
784
+ p(l.data);
785
+ this._onceHandlers.delete(l.name);
786
+ }
738
787
  }
739
788
  for (let c = 0; c < window.frames.length; c += 1)
740
- window.frames[c].postMessage(s.data, "*");
789
+ window.frames[c].postMessage(l, "*");
741
790
  }, window.addEventListener("message", this._windowMessageHandler);
742
791
  }
743
792
  /**
@@ -770,15 +819,15 @@ class j {
770
819
  * @param data The data payload to include with the message
771
820
  */
772
821
  send(e, t) {
773
- const n = b({
774
- telemetrySdkVersion: v,
822
+ const s = S({
823
+ telemetrySdkVersion: N,
775
824
  applicationName: this._applicationName,
776
825
  applicationSpecifier: this._applicationSpecifier,
777
826
  applicationInstance: this._applicationInstance,
778
827
  name: e,
779
828
  data: t
780
829
  });
781
- window.parent.postMessage(n, "*");
830
+ window.parent.postMessage(s, "*");
782
831
  }
783
832
  /**
784
833
  * Sends a message to the TelemetryOS platform and waits for a response.
@@ -798,96 +847,96 @@ class j {
798
847
  * @throws {Error} If the request times out
799
848
  */
800
849
  request(e, t) {
801
- const n = S(), r = b({
802
- telemetrySdkVersion: v,
850
+ const s = v(), o = S({
851
+ telemetrySdkVersion: N,
803
852
  applicationName: this._applicationName,
804
853
  applicationSpecifier: this._applicationSpecifier,
805
854
  applicationInstance: this._applicationInstance,
806
855
  name: e,
807
856
  data: t,
808
- responseName: n
857
+ responseName: s
809
858
  });
810
- window.parent.postMessage(r, "*");
811
- let s = !1, l;
812
- const u = new Promise((h, c) => {
813
- const d = new Error(`${e} message request with response name of ${n} timed out after ${g}`);
859
+ window.parent.postMessage(o, "*");
860
+ let r = !1, n;
861
+ const l = new Promise((h, u) => {
862
+ const p = new Error(`${e} message request with response name of ${s} timed out after ${_}`);
814
863
  setTimeout(() => {
815
- s = !0, this.off(n, l), c(d);
816
- }, g);
817
- }), a = new Promise((h) => {
818
- l = (c) => {
819
- s || h(c);
820
- }, this.once(n, h);
864
+ r = !0, this.off(s, n), u(p);
865
+ }, _);
866
+ }), c = new Promise((h) => {
867
+ n = (u) => {
868
+ r || h(u);
869
+ }, this.once(s, h);
821
870
  });
822
- return Promise.race([u, a]);
871
+ return Promise.race([l, c]);
823
872
  }
824
- async subscribe(e, t, n) {
825
- let r, s;
826
- typeof t == "function" ? s = t : (r = t, s = n);
827
- const l = S(), u = S();
828
- let a = this._subscriptionNamesBySubjectName.get(e);
829
- a || (a = [], this._subscriptionNamesBySubjectName.set(e, a)), a.push(l), this._subscriptionNamesByHandler.set(s, l), this.on(l, s);
830
- const h = b({
831
- telemetrySdkVersion: v,
873
+ async subscribe(e, t, s) {
874
+ let o, r;
875
+ typeof t == "function" ? r = t : (o = t, r = s);
876
+ const n = v(), l = v();
877
+ let c = this._subscriptionNamesBySubjectName.get(e);
878
+ c || (c = [], this._subscriptionNamesBySubjectName.set(e, c)), c.push(n), this._subscriptionNamesByHandler.set(r, n), this.on(n, r);
879
+ const h = S({
880
+ telemetrySdkVersion: N,
832
881
  applicationName: this._applicationName,
833
882
  applicationSpecifier: this._applicationSpecifier,
834
883
  applicationInstance: this._applicationInstance,
835
884
  name: e,
836
- data: r,
837
- responseName: u,
838
- subscriptionName: l
885
+ data: o,
886
+ responseName: l,
887
+ subscriptionName: n
839
888
  });
840
889
  window.parent.postMessage(h, "*");
841
- let c = !1, d;
842
- const N = new Promise((_, f) => {
843
- const m = new Error(`${e} subscribe request with subscription name of ${l} and response name of ${u} timed out after ${g}`);
890
+ let u = !1, p;
891
+ const f = new Promise((w, g) => {
892
+ const m = new Error(`${e} subscribe request with subscription name of ${n} and response name of ${l} timed out after ${_}`);
844
893
  setTimeout(() => {
845
- c = !0, this.off(u, d), f(m);
846
- }, g);
847
- }), H = new Promise((_) => {
848
- d = (f) => {
849
- c || _(f);
850
- }, this.on(u, _);
894
+ u = !0, this.off(l, p), g(m);
895
+ }, _);
896
+ }), I = new Promise((w) => {
897
+ p = (g) => {
898
+ u || w(g);
899
+ }, this.on(l, w);
851
900
  });
852
- return Promise.race([N, H]);
901
+ return Promise.race([f, I]);
853
902
  }
854
- async unsubscribe(e, t, n) {
855
- let r, s;
856
- typeof t == "function" ? s = t : (r = t, s = n);
857
- const l = S();
858
- let u = [];
859
- if (s) {
860
- const a = this._subscriptionNamesByHandler.get(s);
861
- if (!a)
903
+ async unsubscribe(e, t, s) {
904
+ let o, r;
905
+ typeof t == "function" ? r = t : (o = t, r = s);
906
+ const n = v();
907
+ let l = [];
908
+ if (r) {
909
+ const c = this._subscriptionNamesByHandler.get(r);
910
+ if (!c)
862
911
  return { success: !1 };
863
- u = [a], this._subscriptionNamesByHandler.delete(s);
912
+ l = [c], this._subscriptionNamesByHandler.delete(r);
864
913
  } else if (!this._subscriptionNamesBySubjectName.get(e))
865
914
  return { success: !1 };
866
- for await (const a of u) {
867
- this.off(a, s);
868
- const h = b({
869
- telemetrySdkVersion: v,
915
+ for await (const c of l) {
916
+ this.off(c, r);
917
+ const h = S({
918
+ telemetrySdkVersion: N,
870
919
  applicationInstance: this._applicationInstance,
871
920
  applicationName: this._applicationName,
872
921
  applicationSpecifier: this._applicationSpecifier,
873
922
  name: e,
874
- data: r,
875
- responseName: l,
876
- unsubscribeName: a
923
+ data: o,
924
+ responseName: n,
925
+ unsubscribeName: c
877
926
  });
878
927
  window.parent.postMessage(h, "*");
879
- let c = !1, d;
880
- const N = new Promise((f, m) => {
881
- const q = new Error(`${e} unsubscribe request with unsubscribe name of ${a} and response name of ${l} timed out after ${g}`);
928
+ let u = !1, p;
929
+ const f = new Promise((g, m) => {
930
+ const H = new Error(`${e} unsubscribe request with unsubscribe name of ${c} and response name of ${n} timed out after ${_}`);
882
931
  setTimeout(() => {
883
- c = !0, this.off(l, d), m(q);
884
- }, g);
885
- }), H = new Promise((f) => {
886
- d = (m) => {
887
- c || f(m);
888
- }, this.once(l, f);
932
+ u = !0, this.off(n, p), m(H);
933
+ }, _);
934
+ }), I = new Promise((g) => {
935
+ p = (m) => {
936
+ u || g(m);
937
+ }, this.once(n, g);
889
938
  });
890
- if (!(await Promise.race([N, H])).success)
939
+ if (!(await Promise.race([f, I])).success)
891
940
  return { success: !1 };
892
941
  }
893
942
  return { success: !0 };
@@ -910,9 +959,9 @@ class j {
910
959
  * @param handler The callback function to execute when messages are received
911
960
  */
912
961
  on(e, t) {
913
- var n;
914
- const r = (n = this._onHandlers.get(e)) !== null && n !== void 0 ? n : [];
915
- r.length === 0 && this._onHandlers.set(e, r), r.push(t);
962
+ var s;
963
+ const o = (s = this._onHandlers.get(e)) !== null && s !== void 0 ? s : [];
964
+ o.length === 0 && this._onHandlers.set(e, o), o.push(t);
916
965
  }
917
966
  /**
918
967
  * Registers a one-time handler for a specific message type.
@@ -929,9 +978,9 @@ class j {
929
978
  * @param handler The callback function to execute when the message is received
930
979
  */
931
980
  once(e, t) {
932
- var n;
933
- const r = (n = this._onceHandlers.get(e)) !== null && n !== void 0 ? n : [];
934
- r.length === 0 && this._onceHandlers.set(e, r), r.push(t);
981
+ var s;
982
+ const o = (s = this._onceHandlers.get(e)) !== null && s !== void 0 ? s : [];
983
+ o.length === 0 && this._onceHandlers.set(e, o), o.push(t);
935
984
  }
936
985
  /**
937
986
  * Removes previously registered message handlers.
@@ -949,97 +998,98 @@ class j {
949
998
  * all handlers for this message type will be removed.
950
999
  */
951
1000
  off(e, t) {
952
- const n = this._onHandlers.get(e), r = this._onceHandlers.get(e);
953
- if (!(!n && !r)) {
954
- if (n) {
955
- for (let s = 0; s < n.length; s += 1)
956
- t && n[s] !== t || (n.splice(s, 1), s -= 1);
957
- n.length === 0 && this._onHandlers.delete(e);
1001
+ const s = this._onHandlers.get(e), o = this._onceHandlers.get(e);
1002
+ if (!(!s && !o)) {
1003
+ if (s) {
1004
+ for (let r = 0; r < s.length; r += 1)
1005
+ t && s[r] !== t || (s.splice(r, 1), r -= 1);
1006
+ s.length === 0 && this._onHandlers.delete(e);
958
1007
  }
959
- if (r) {
960
- for (let s = 0; s < r.length; s += 1)
961
- t && r[s] !== t || (r.splice(s, 1), s -= 1);
962
- r.length === 0 && this._onceHandlers.delete(e);
1008
+ if (o) {
1009
+ for (let r = 0; r < o.length; r += 1)
1010
+ t && o[r] !== t || (o.splice(r, 1), r -= 1);
1011
+ o.length === 0 && this._onceHandlers.delete(e);
963
1012
  }
964
1013
  }
965
1014
  }
966
1015
  }
967
- function S() {
1016
+ function v() {
968
1017
  return Math.random().toString(36).slice(2, 9);
969
1018
  }
970
- const v = P.version;
1019
+ const N = E.version;
971
1020
  let i = null;
972
1021
  function U() {
973
1022
  return i;
974
1023
  }
975
- function V(o) {
976
- i = new j(o), i.bind();
1024
+ function V(a) {
1025
+ i = new j(a), i.bind();
977
1026
  }
978
1027
  function z() {
979
1028
  i == null || i.unbind(), i = null;
980
1029
  }
981
- function G(...o) {
982
- return p(i), i.on(...o);
1030
+ function G(...a) {
1031
+ return d(i), i.on(...a);
983
1032
  }
984
- function J(...o) {
985
- return p(i), i.once(...o);
1033
+ function J(...a) {
1034
+ return d(i), i.once(...a);
986
1035
  }
987
- function K(...o) {
988
- return p(i), i.off(...o);
1036
+ function K(...a) {
1037
+ return d(i), i.off(...a);
989
1038
  }
990
- function O(...o) {
991
- return p(i), i.send(...o);
1039
+ function O(...a) {
1040
+ return d(i), i.send(...a);
992
1041
  }
993
- function W(...o) {
994
- return p(i), i.request(...o);
1042
+ function W(...a) {
1043
+ return d(i), i.request(...a);
995
1044
  }
996
- function Q(...o) {
997
- return p(i), i.subscribe(...o);
1045
+ function Q(...a) {
1046
+ return d(i), i.subscribe(...a);
998
1047
  }
999
- function X(...o) {
1000
- return p(i), i.unsubscribe(...o);
1048
+ function X(...a) {
1049
+ return d(i), i.unsubscribe(...a);
1001
1050
  }
1002
1051
  function Y() {
1003
- return p(i), i.store;
1052
+ return d(i), i.store;
1004
1053
  }
1005
1054
  function Z() {
1006
- return p(i), i.applications;
1055
+ return d(i), i.applications;
1007
1056
  }
1008
1057
  function ee() {
1009
- return p(i), i.media;
1058
+ return d(i), i.media;
1010
1059
  }
1011
1060
  function te() {
1012
- return p(i), i.accounts;
1061
+ return d(i), i.accounts;
1013
1062
  }
1014
1063
  function se() {
1015
- return p(i), i.users;
1064
+ return d(i), i.users;
1016
1065
  }
1017
1066
  function ne() {
1018
- return p(i), i.devices;
1067
+ return d(i), i.devices;
1019
1068
  }
1020
1069
  function ie() {
1021
- return p(i), i.proxy;
1070
+ return d(i), i.proxy;
1022
1071
  }
1023
1072
  function re() {
1024
- return p(i), i.rootSettingsNavigation;
1073
+ return d(i), i.rootSettingsNavigation;
1025
1074
  }
1026
1075
  function oe() {
1027
- return p(i), i.weather;
1076
+ return d(i), i.weather;
1028
1077
  }
1029
- function p(o) {
1030
- if (!o)
1078
+ function d(a) {
1079
+ if (!a)
1031
1080
  throw new Error("SDK is not configured");
1032
1081
  }
1033
1082
  export {
1034
- E as Accounts,
1035
- M as Applications,
1083
+ M as Accounts,
1084
+ P as Applications,
1036
1085
  j as Client,
1037
- A as Devices,
1086
+ C as Devices,
1038
1087
  L as Environment,
1039
- C as Media,
1088
+ B as Media,
1089
+ T as Proxy,
1040
1090
  F as Store,
1041
1091
  k as Users,
1042
- T as Weather,
1092
+ $ as Weather,
1043
1093
  te as accounts,
1044
1094
  Z as applications,
1045
1095
  V as configure,
@@ -1056,7 +1106,7 @@ export {
1056
1106
  O as send,
1057
1107
  Y as store,
1058
1108
  Q as subscribe,
1059
- v as telemetrySdkVersion,
1109
+ N as telemetrySdkVersion,
1060
1110
  X as unsubscribe,
1061
1111
  se as users,
1062
1112
  oe as weather
package/dist/proxy.d.ts CHANGED
@@ -12,15 +12,12 @@ export declare class Proxy {
12
12
  /**
13
13
  * Fetches content from an external URL through the TelemetryOS API.
14
14
  *
15
- * This method has the same interface as the native `fetch()` API but routes the request through
16
- * the platform. This is useful for:
17
- * - Accessing external APIs that have CORS restrictions
18
- * - Fetching content with platform authentication
19
- * - Benefiting from platform caching and bandwidth management
20
- * - Proxying content from external sources
15
+ * This method is a subset of the native `fetch()` API that routes requests through
16
+ * the platform. Only `method`, `headers`, and `body` options are supported.
17
+ * AbortSignal and other fetch options are not supported.
21
18
  *
22
- * @param input The URL to fetch from (as a string or URL object)
23
- * @param init Optional fetch options (method, headers, body, signal, etc.)
19
+ * @param input The URL to fetch from (as a string, URL, or Request object)
20
+ * @param init Optional fetch options (method, headers, body)
24
21
  * @returns A promise that resolves to a standard Response object
25
22
  *
26
23
  * @example
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telemetryos/root-sdk",
3
- "version": "1.4.4",
3
+ "version": "1.5.1",
4
4
  "description": "The official TelemetryOS root application sdk package. Provides types and apis for building root TelemetryOS applications.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",