@telemetryos/root-sdk 1.1.0 → 1.3.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/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # @telemetryos/root-sdk
2
+
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add Weather API
8
+
9
+ Adds a weather API for applications that wish to use it. It can be found on
10
+ client instances under .weather.
11
+
12
+ ## 1.2.0
13
+
14
+ ### Minor Changes
15
+
16
+ - Added setDependencies to applications api
package/README.md CHANGED
@@ -189,16 +189,19 @@ Access media content uploaded to TelemetryOS:
189
189
  ```javascript
190
190
  import { media } from '@telemetryos/root-sdk';
191
191
 
192
- // Get media folders by tag
193
- const folders = await media().getFoldersByTag('marketing');
192
+ // Get all media folders
193
+ const folders = await media().getAllFolders();
194
194
 
195
- // Get content from a folder
196
- const content = await media().getMediaContentByFolderId(folderId);
195
+ // Get all content in a specific folder
196
+ const content = await media().getAllByFolderId(folderId);
197
197
 
198
- // Access the media file URLs
199
- const mediaItem = await media().getMediaContentById(mediaId);
198
+ // Get content by tag
199
+ const taggedContent = await media().getAllByTag('marketing');
200
200
 
201
- // Use this URL to display/play the media
201
+ // Get a specific content item by ID
202
+ const mediaItem = await media().getById(mediaId);
203
+
204
+ // Use the public URL to display/play the media
202
205
  const publicUrl = mediaItem.publicUrls[0];
203
206
  ```
204
207
 
@@ -213,8 +216,60 @@ import { accounts, users } from '@telemetryos/root-sdk';
213
216
  const account = await accounts().getCurrent();
214
217
 
215
218
  // Get current user
216
- const userResult = await users().getCurrent();
217
- const userId = userResult.user.id;
219
+ const user = await users().getCurrent();
220
+ const userId = user.id;
221
+ ```
222
+
223
+ ### Device Information
224
+
225
+ Access information about the device the application is running on:
226
+
227
+ ```javascript
228
+ import { devices } from '@telemetryos/root-sdk';
229
+
230
+ // Get current device information
231
+ const device = await devices().getCurrent();
232
+ console.log(`Device: ${device.name}`);
233
+
234
+ // Get hardware information
235
+ const hardwareInfo = await devices().getInformation();
236
+ console.log(`Device: ${hardwareInfo.deviceManufacturer} ${hardwareInfo.deviceModel}`);
237
+
238
+ // Subscribe to device changes
239
+ await devices().subscribeCurrent((data) => {
240
+ if (data.type === 'device_changed') {
241
+ console.log('Device updated:', data.device);
242
+ } else if (data.type === 'device_removed') {
243
+ console.log('Device removed:', data.device.id);
244
+ }
245
+ });
246
+
247
+ // Unsubscribe when done
248
+ await devices().unsubscribeCurrent(myHandler);
249
+ ```
250
+
251
+ ### Proxy API
252
+
253
+ Fetch external content through the TelemetryOS proxy service:
254
+
255
+ ```javascript
256
+ import { proxy } from '@telemetryos/root-sdk';
257
+
258
+ // Fetch JSON from an external API
259
+ const response = await proxy().fetch('https://api.example.com/data');
260
+ const data = await response.json();
261
+
262
+ // POST data to an external API
263
+ const response = await proxy().fetch('https://api.example.com/submit', {
264
+ method: 'POST',
265
+ headers: { 'Content-Type': 'application/json' },
266
+ body: JSON.stringify({ key: 'value' })
267
+ });
268
+
269
+ // Fetch an image through the proxy
270
+ const response = await proxy().fetch('https://example.com/image.jpg');
271
+ const blob = await response.blob();
272
+ const imageUrl = URL.createObjectURL(blob);
218
273
  ```
219
274
 
220
275
  ## Communication Patterns
@@ -387,7 +442,7 @@ This section provides structured examples of common implementation patterns to h
387
442
  import { media } from '@telemetryos/root-sdk';
388
443
 
389
444
  async function displayMedia(mediaId) {
390
- const mediaItem = await media().getMediaContentById(mediaId);
445
+ const mediaItem = await media().getById(mediaId);
391
446
  const mediaElement = document.createElement('img');
392
447
  mediaElement.src = mediaItem.publicUrls[0];
393
448
  document.body.appendChild(mediaElement);
@@ -467,8 +522,8 @@ Always implement proper error handling for SDK operations:
467
522
 
468
523
  ```javascript
469
524
  try {
470
- const result = await media().getFoldersByTag('marketing');
471
- displayFolders(result);
525
+ const result = await media().getAllByTag('marketing');
526
+ displayContent(result);
472
527
  } catch (error) {
473
528
  // Check for timeout errors
474
529
  if (error.message.includes('timed out')) {
@@ -476,7 +531,7 @@ try {
476
531
  } else {
477
532
  showGenericError();
478
533
  }
479
-
534
+
480
535
  // Provide fallback content or retry strategy
481
536
  displayCachedContent();
482
537
  }
@@ -10,6 +10,10 @@ export type Application = {
10
10
  export type GetUrlResult = {
11
11
  url: string;
12
12
  };
13
+ export type SetDependenciesResult = {
14
+ ready: string[];
15
+ unavailable: string[];
16
+ };
13
17
  export declare class Applications {
14
18
  _client: Client;
15
19
  constructor(client: Client);
@@ -39,17 +43,23 @@ export declare class Applications {
39
43
  */
40
44
  getByName(name: string): Promise<Application | null>;
41
45
  /**
42
- * Generates a URL for embedding an application with the specified name and mount point.
46
+ * Sets the dependencies for the current application.
47
+ *
48
+ * This method allows an application to declare which other applications it depends on.
49
+ * The player will download and prepare these dependencies before they can be loaded.
43
50
  *
44
- * This method returns a URL that can be used in an iframe src attribute to embed
45
- * the application. The URL includes necessary parameters for the application to
46
- * understand its context and communicate with the platform.
51
+ * IMPORTANT: This method must be called and awaited before loading any sub-applications
52
+ * in iframes. Only applications that return as 'ready' should be loaded.
47
53
  *
48
- * Only applications that are associated with the current account can be retrieved.
54
+ * @param applicationSpecifiers An array of application specifiers that this application depends on
55
+ * @returns A promise that resolves with arrays of ready and unavailable application specifiers
49
56
  *
50
- * @param name The name of the application to get the URL for
51
- * @param mountPoint The mount point to use when embedding the application
52
- * @returns A promise that resolves to the URL string for embedding the application
57
+ * @example
58
+ * ```typescript
59
+ * const result = await client.applications.setDependencies(['app1-hash', 'app2-hash'])
60
+ * // result.ready: ['app1-hash'] - these can be loaded in iframes
61
+ * // result.unavailable: ['app2-hash'] - these failed to load
62
+ * ```
53
63
  */
54
- getUrl(name: string, mountPoint: string): Promise<string>;
64
+ setDependencies(applicationSpecifiers: string[]): Promise<SetDependenciesResult>;
55
65
  }
package/dist/client.d.ts CHANGED
@@ -4,6 +4,9 @@ import { Store } from './store.js';
4
4
  import { RootSettingsNavigation } from './root-settings-navigation.js';
5
5
  import { Accounts } from './accounts.js';
6
6
  import { Users } from './users.js';
7
+ import { Proxy } from './proxy.js';
8
+ import { Devices } from './device.js';
9
+ import { Weather } from './weather.js';
7
10
  /**
8
11
  * The maximum time in milliseconds to wait for a response to a request call.
9
12
  *
@@ -91,7 +94,7 @@ export declare class Client {
91
94
  * Provides access to the store API for data persistence with multiple storage scopes.
92
95
  *
93
96
  * This property returns a new Store instance that allows saving, retrieving, and
94
- * subscribing to data changes across different scopes (global, local, deviceLocal, shared).
97
+ * subscribing to data changes across different scopes (application, instance, device, shared).
95
98
  *
96
99
  * NOTE: Most application developers should use the global store() function
97
100
  * instead of accessing this property directly.
@@ -100,10 +103,10 @@ export declare class Client {
100
103
  */
101
104
  get store(): Store;
102
105
  /**
103
- * Provides access to the applications API for discovering and embedding other TelemetryOS applications.
106
+ * Provides access to the applications API for discovering other TelemetryOS applications.
104
107
  *
105
108
  * This property returns a new Applications instance that allows querying for applications
106
- * by name or mount point, and generating URLs for embedding applications in iframes.
109
+ * by name or mount point, and setting application dependencies.
107
110
  *
108
111
  * NOTE: Most application developers should use the global applications() function
109
112
  * instead of accessing this property directly.
@@ -124,6 +127,31 @@ export declare class Client {
124
127
  * @returns A Media instance bound to this client
125
128
  */
126
129
  get media(): Media;
130
+ /**
131
+ * Provides access to the proxy API for fetching third-party content through the TelemetryOS proxy service.
132
+ *
133
+ * This property returns a new Proxy instance that allows applications to fetch content from external
134
+ * URLs through the platform's proxy service, which handles authentication, caching, and CORS issues.
135
+ *
136
+ * NOTE: Most application developers should use the global proxy() function
137
+ * instead of accessing this property directly.
138
+ *
139
+ * @returns A Proxy instance bound to this client
140
+ */
141
+ get proxy(): Proxy;
142
+ /**
143
+ * Provides access to the devices API for interacting with the current device.
144
+ *
145
+ * This property returns a new Devices instance that allows applications to get information
146
+ * about the specific device the application is running on, subscribe to device changes,
147
+ * and access device hardware information.
148
+ *
149
+ * NOTE: Most application developers should use the global devices() function
150
+ * instead of accessing this property directly.
151
+ *
152
+ * @returns A Devices instance bound to this client
153
+ */
154
+ get devices(): Devices;
127
155
  /**
128
156
  * Provides access to the root settings navigation API for TelemetryOS administration UI integration.
129
157
  *
@@ -140,6 +168,19 @@ export declare class Client {
140
168
  * @throws {Error} If used by an application not mounted at the 'rootSettingsNavigation' mount point
141
169
  */
142
170
  get rootSettingsNavigation(): RootSettingsNavigation;
171
+ /**
172
+ * Provides access to the weather API for retrieving weather data.
173
+ *
174
+ * This property returns a new Weather instance that allows applications to fetch
175
+ * current weather conditions and forecasts from various providers (WeatherBit, AccuWeather)
176
+ * through the General Integrations Service.
177
+ *
178
+ * NOTE: Most application developers should use the global weather() function
179
+ * instead of accessing this property directly.
180
+ *
181
+ * @returns A Weather instance bound to this client
182
+ */
183
+ get weather(): Weather;
143
184
  get applicationName(): string;
144
185
  get applicationSpecifier(): string;
145
186
  get applicationInstance(): string;
@@ -0,0 +1,26 @@
1
+ import { Client } from './client.js';
2
+ type DeviceInformation = {
3
+ deviceSerialNumber: string;
4
+ deviceModel: string;
5
+ deviceManufacturer: string;
6
+ devicePlatform: string;
7
+ };
8
+ export declare class Devices {
9
+ _client: Client;
10
+ constructor(client: Client);
11
+ /**
12
+ * Retrieves hardware information about the current physical device.
13
+ *
14
+ * This method returns details about the device running the application, such as
15
+ * serial number, model, manufacturer, and platform. This information is only
16
+ * available when running on a physical device (player), not in the admin UI.
17
+ *
18
+ * @returns A promise that resolves to the device hardware information
19
+ * @example
20
+ * // Get hardware info of the current device
21
+ * const info = await devices.getInformation();
22
+ * console.log(`Device: ${info.deviceManufacturer} ${info.deviceModel}`);
23
+ */
24
+ getInformation(): Promise<DeviceInformation>;
25
+ }
26
+ export {};
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("./index-JDXm3DEz.cjs"),k="1.1.0",E={version:k};class I{constructor(e){this._client=e}async getCurrent(){return(await this._client.request("user.getCurrentAccount",{})).account}}class M{constructor(e){this._client=e}async getAllByMountPoint(e){return(await this._client.request("applications.getByMountPoint",{mountPoint:e})).applications}async getByName(e){return(await this._client.request("applications.getByName",{name:e})).application}async getUrl(e,t){return(await this._client.request("applications.getUrl",{name:e,mountPoint:t})).url}}function A(o,e=console.error){o().catch(e)}class ${constructor(e){this._client=e}async getColorScheme(){return(await this._client.request("environment.getColorScheme",{})).colorScheme}subscribeColorScheme(e){A(async()=>{this._client.on("environment.colorSchemeChanged",e),e(await this.getColorScheme())})}unsubscribeColorScheme(e){this._client.off("environment.colorSchemeChanged",e)}}class q{constructor(e){this._client=e}async queryFolders(e){return(await this._client.request("media.queryMediaFolders",{query:e})).folders}async getFoldersByTag(e){return(await this._client.request("media.getMediaFoldersByTag",{tagName:e})).folders}async getFolderById(e){return(await this._client.request("media.getMediaFolderById",{id:e})).folder}async getMediaContentByFolderId(e){return(await this._client.request("media.getMediaContentByFolderId",{folderId:e})).folders}async getMediaContentById(e){return(await this._client.request("media.getMediaContentById",{id:e})).content}}class H{constructor(e){this._client=e}get application(){return new b("application","",this._client)}get instance(){return new b("instance",this._client._applicationId,this._client)}get device(){return new b("device",this._client._applicationId,this._client)}shared(e){return new b("shared",e,this._client)}}class b{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 P{constructor(e){this._client=e}async getCurrent(){return await this._client.request("user.getCurrentUser",{})}}const T=v.z.object({name:v.z.string(),data:v.z.any()});class F{constructor(e){if(e._client._applicationId!=="rootSettingsNavigation")throw new Error("RootSettingsNavigation can only be used in the rootSettingsNavigation mount point");this._store=e}async setRootSettingsNavigation(e){const t=this._store.shared("root-settings-navigation"),s=await t.get("navigation"),r=this._store._client._applicationId;s[r]={applicationId:r,entries:e.entries},t.set("navigation",s)}async getRootSettingsNavigation(){const t=await this._store.shared("root-settings-navigation").get("navigation"),s=this._store._client._applicationId;return t[s]}async getAllRootSettingsNavigation(){return this._store.shared("root-settings-navigation").get("navigation")}}const f=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 I(this)}get users(){return new P(this)}get store(){return new H(this)}get applications(){return new M(this)}get media(){return new q(this)}get rootSettingsNavigation(){return new F(this.store)}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),s=t.searchParams;this._applicationInstance=(e=s.get("telemetryApplicationId"))!==null&&e!==void 0?e:"";const r=s.get("applicationSpecifier");if(r)this._applicationSpecifier=r;else{const i=t.hostname.split(".");this._applicationSpecifier=i[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=i=>{if(i.source===window)return;for(let c=0;c<window.frames.length;c+=1)window.frames[c].postMessage(i.data,"*");const l=T.safeParse(i.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)}},window.addEventListener("message",this._windowMessageHandler)}unbind(){this._windowMessageHandler&&window.removeEventListener("message",this._windowMessageHandler)}send(e,t){const s={telemetrySdkVersion:_,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,applicationInstance:this._applicationInstance,name:e,data:t};window.parent.postMessage(s,"*")}request(e,t){const s=y(),r={telemetrySdkVersion:_,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,applicationInstance:this._applicationInstance,name:e,data:t,responseName:s};window.parent.postMessage(r,"*");let i=!1,l;const u=new Promise((h,c)=>{const d=new Error(`${e} message request with response name of ${s} timed out after ${f}`);setTimeout(()=>{i=!0,this.off(s,l),c(d)},f)}),a=new Promise(h=>{l=c=>{i||h(c)},this.once(s,h)});return Promise.race([u,a])}async subscribe(e,t,s){let r,i;typeof t=="function"?i=t:(r=t,i=s);const l=y(),u=y();let a=this._subscriptionNamesBySubjectName.get(e);a||(a=[],this._subscriptionNamesBySubjectName.set(e,a)),a.push(l),this._subscriptionNamesByHandler.set(i,l),this.on(l,i);const h={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 S=new Promise((w,g)=>{const m=new Error(`${e} subscribe request with subscription name of ${l} and response name of ${u} timed out after ${f}`);setTimeout(()=>{c=!0,this.off(u,d),g(m)},f)}),N=new Promise(w=>{d=g=>{c||w(g)},this.on(u,w)});return Promise.race([S,N])}async unsubscribe(e,t,s){let r,i;typeof t=="function"?i=t:(r=t,i=s);const l=y();let u=[];if(i){const a=this._subscriptionNamesByHandler.get(i);if(!a)return{success:!1};u=[a],this._subscriptionNamesByHandler.delete(i)}else if(!this._subscriptionNamesBySubjectName.get(e))return{success:!1};for await(const a of u){this.off(a,i);const h={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 S=new Promise((g,m)=>{const B=new Error(`${e} unsubscribe request with unsubscribe name of ${a} and response name of ${l} timed out after ${f}`);setTimeout(()=>{c=!0,this.off(l,d),m(B)},f)}),N=new Promise(g=>{d=m=>{c||g(m)},this.once(l,g)});if(!(await Promise.race([S,N])).success)return{success:!1}}return{success:!0}}on(e,t){var s;const r=(s=this._onHandlers.get(e))!==null&&s!==void 0?s:[];r.length===0&&this._onHandlers.set(e,r),r.push(t)}once(e,t){var s;const r=(s=this._onceHandlers.get(e))!==null&&s!==void 0?s:[];r.length===0&&this._onceHandlers.set(e,r),r.push(t)}off(e,t){const s=this._onHandlers.get(e),r=this._onceHandlers.get(e);if(!(!s&&!r)){if(s){for(let i=0;i<s.length;i+=1)t&&s[i]!==t||(s.splice(i,1),i-=1);s.length===0&&this._onHandlers.delete(e)}if(r){for(let i=0;i<r.length;i+=1)t&&r[i]!==t||(r.splice(i,1),i-=1);r.length===0&&this._onceHandlers.delete(e)}}}}function y(){return Math.random().toString(36).slice(2,9)}const _=E.version;let n=null;function R(){return n}function j(o){n=new C(o),n.bind()}function U(){n==null||n.unbind(),n=null}function z(...o){return p(n),n.on(...o)}function L(...o){return p(n),n.once(...o)}function V(...o){return p(n),n.off(...o)}function x(...o){return p(n),n.send(...o)}function D(...o){return p(n),n.request(...o)}function K(...o){return p(n),n.subscribe(...o)}function G(...o){return p(n),n.unsubscribe(...o)}function J(){return p(n),n.store}function O(){return p(n),n.applications}function Q(){return p(n),n.media}function W(){return p(n),n.accounts}function X(){return p(n),n.users}function Y(){return p(n),n.rootSettingsNavigation}function p(o){if(!o)throw new Error("SDK is not configured")}exports.Accounts=I;exports.Applications=M;exports.Client=C;exports.Environment=$;exports.Media=q;exports.Store=H;exports.Users=P;exports.accounts=W;exports.applications=O;exports.configure=j;exports.destroy=U;exports.globalClient=R;exports.media=Q;exports.off=V;exports.on=z;exports.once=L;exports.request=D;exports.rootSettingsNavigation=Y;exports.send=x;exports.store=J;exports.subscribe=K;exports.telemetrySdkVersion=_;exports.unsubscribe=G;exports.users=X;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N=require("./index-JDXm3DEz.cjs"),B="1.3.0",k={version:B};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})}}class A{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 T(o,e=console.error){o().catch(e)}class ${constructor(e){this._client=e}async getColorScheme(){return(await this._client.request("environment.getColorScheme",{})).colorScheme}subscribeColorScheme(e){T(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 I{constructor(e){this._client=e}get application(){return new y("application","",this._client)}get instance(){return new y("instance",this._client.applicationSpecifier,this._client)}get device(){return new y("device",this._client.applicationSpecifier,this._client)}shared(e){return new y("shared",e,this._client)}}class y{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 P{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 M{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}async getAccuWeatherConditions(e){const t=await this._client.request("weather.getAccuWeatherConditions",e);if(!t.success||!t.data)throw new Error(t.error||"Failed to fetch AccuWeather conditions");return t.data}async getAccuWeatherDailyForecast(e){const t=await this._client.request("weather.getAccuWeatherDailyForecast",e);if(!t.success||!t.data)throw new Error(t.error||"Failed to fetch AccuWeather daily forecast");return t.data}async getAccuWeatherHourlyForecast(e){const t=await this._client.request("weather.getAccuWeatherHourlyForecast",e);if(!t.success||!t.data)throw new Error(t.error||"Failed to fetch AccuWeather hourly forecast");return t.data}}const x=N.z.object({name:N.z.string(),data:N.z.any()});class W{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){const t=this._store.shared("root-settings-navigation"),n=await t.get("navigation"),r=this._store._client._applicationSpecifier;n[r]={applicationSpecifier:r,entries:e.entries},t.set("navigation",n)}async getRootSettingsNavigation(){const t=await this._store.shared("root-settings-navigation").get("navigation"),n=this._store._client._applicationSpecifier;return t[n]}async getAllRootSettingsNavigation(){return this._store.shared("root-settings-navigation").get("navigation")}}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((p,c)=>{r[c]=p}):Array.isArray(t.headers)?t.headers.forEach(([p,c])=>{r[p]=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 H(this)}get users(){return new P(this)}get store(){return new I(this)}get applications(){return new q(this)}get media(){return new E(this)}get proxy(){return new D(this)}get devices(){return new A(this)}get rootSettingsNavigation(){return new W(this.store)}get weather(){return new M(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)return;for(let c=0;c<window.frames.length;c+=1)window.frames[c].postMessage(s.data,"*");const l=x.safeParse(s.data);if(!l.success)return;const u=l.data,a=this._onHandlers.get(u.name),p=this._onceHandlers.get(u.name);if(a)for(const c of a)c(u.data);if(p){for(const c of p)c(u.data);this._onceHandlers.delete(u.name)}},window.addEventListener("message",this._windowMessageHandler)}unbind(){this._windowMessageHandler&&window.removeEventListener("message",this._windowMessageHandler)}send(e,t){const n={telemetrySdkVersion:w,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,applicationInstance:this._applicationInstance,name:e,data:t};window.parent.postMessage(n,"*")}request(e,t){const n=b(),r={telemetrySdkVersion:w,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((p,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(p=>{l=c=>{s||p(c)},this.once(n,p)});return Promise.race([u,a])}async subscribe(e,t,n){let r,s;typeof t=="function"?s=t:(r=t,s=n);const l=b(),u=b();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 p={telemetrySdkVersion:w,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,applicationInstance:this._applicationInstance,name:e,data:r,responseName:u,subscriptionName:l};window.parent.postMessage(p,"*");let c=!1,d;const S=new Promise((_,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)}),v=new Promise(_=>{d=f=>{c||_(f)},this.on(u,_)});return Promise.race([S,v])}async unsubscribe(e,t,n){let r,s;typeof t=="function"?s=t:(r=t,s=n);const l=b();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 p={telemetrySdkVersion:w,applicationInstance:this._applicationInstance,applicationName:this._applicationName,applicationSpecifier:this._applicationSpecifier,name:e,data:r,responseName:l,unsubscribeName:a};window.parent.postMessage(p,"*");let c=!1,d;const S=new Promise((f,m)=>{const F=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(F)},g)}),v=new Promise(f=>{d=m=>{c||f(m)},this.once(l,f)});if(!(await Promise.race([S,v])).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 b(){return Math.random().toString(36).slice(2,9)}const w=k.version;let i=null;function R(){return i}function j(o){i=new C(o),i.bind()}function L(){i==null||i.unbind(),i=null}function U(...o){return h(i),i.on(...o)}function z(...o){return h(i),i.once(...o)}function V(...o){return h(i),i.off(...o)}function O(...o){return h(i),i.send(...o)}function G(...o){return h(i),i.request(...o)}function J(...o){return h(i),i.subscribe(...o)}function K(...o){return h(i),i.unsubscribe(...o)}function Q(){return h(i),i.store}function X(){return h(i),i.applications}function Y(){return h(i),i.media}function Z(){return h(i),i.accounts}function ee(){return h(i),i.users}function te(){return h(i),i.devices}function se(){return h(i),i.proxy}function ne(){return h(i),i.rootSettingsNavigation}function ie(){return h(i),i.weather}function h(o){if(!o)throw new Error("SDK is not configured")}exports.Accounts=H;exports.Applications=q;exports.Client=C;exports.Devices=A;exports.Environment=$;exports.Media=E;exports.Store=I;exports.Users=P;exports.Weather=M;exports.accounts=Z;exports.applications=X;exports.configure=j;exports.destroy=L;exports.devices=te;exports.globalClient=R;exports.media=Y;exports.off=V;exports.on=U;exports.once=z;exports.proxy=se;exports.request=G;exports.rootSettingsNavigation=ne;exports.send=O;exports.store=Q;exports.subscribe=J;exports.telemetrySdkVersion=w;exports.unsubscribe=K;exports.users=ee;exports.weather=ie;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  export { Accounts } from './accounts.js';
2
2
  export { Applications } from './applications.js';
3
+ export { Devices } from './device.js';
3
4
  export { Environment } from './environment.js';
4
5
  export { Media } from './media.js';
5
6
  export { Store } from './store.js';
6
7
  export { Users } from './users.js';
8
+ export { Weather } from './weather.js';
9
+ export type { WeatherConditions, WeatherForecast, WeatherRequestParams, DailyForecastParams, HourlyForecastParams, } from './weather.js';
7
10
  import { Client } from './client.js';
8
11
  export { Client, type SubscriptionResult, type MessageHandler } from './client.js';
9
12
  /**
@@ -161,10 +164,10 @@ export declare function unsubscribe(...args: Parameters<Client['unsubscribe']>):
161
164
  * The store API allows you to save, retrieve, and subscribe to data changes. It offers
162
165
  * four different storage scopes for different persistence needs:
163
166
  *
164
- * - global: Data shared across all instances of this application within an account
165
- * - local: Data specific to the current instance of this application
166
- * - deviceLocal: Data available only on the current device
167
- * - shared: Data shared between different applications through a common namespace
167
+ * - application: Data shared across all instances of this application within an account
168
+ * - instance: Data specific to the current instance of this application
169
+ * - device: Data available only on the current device
170
+ * - shared(namespace): Data shared between different applications through a common namespace
168
171
  *
169
172
  * Applications should generally use subscribe() for real-time data access since they may
170
173
  * run indefinitely and need to respond to changes. The get() method is provided primarily
@@ -175,11 +178,11 @@ export declare function unsubscribe(...args: Parameters<Client['unsubscribe']>):
175
178
  */
176
179
  export declare function store(): import("./store.js").Store;
177
180
  /**
178
- * Provides access to the applications API for embedding other TelemetryOS applications.
181
+ * Provides access to the applications API for discovering other TelemetryOS applications.
179
182
  *
180
- * This API enables applications to discover and embed other applications within the
181
- * TelemetryOS ecosystem. It allows querying for applications by name or mount point,
182
- * and generating URLs that can be used to load applications in iframes.
183
+ * This API enables applications to discover other applications within the TelemetryOS
184
+ * ecosystem. It allows querying for applications by name or mount point, and setting
185
+ * application dependencies.
183
186
  *
184
187
  * @returns The Applications API object
185
188
  * @throws {Error} If called before configure() or after destroy()
@@ -207,6 +210,31 @@ export declare function accounts(): import("./accounts.js").Accounts;
207
210
  * @throws {Error} If called before configure() or after destroy()
208
211
  */
209
212
  export declare function users(): import("./users.js").Users;
213
+ /**
214
+ * Provides access to the devices API for interacting with the current device.
215
+ *
216
+ * This API allows applications to get information about the specific device the application
217
+ * is currently running on, subscribe to device changes, and access device hardware information.
218
+ *
219
+ * @returns The Devices API object
220
+ * @throws {Error} If called before configure() or after destroy()
221
+ */
222
+ export declare function devices(): import("./device.js").Devices;
223
+ /**
224
+ * Provides access to the proxy API for fetching third-party content through the TelemetryOS proxy service.
225
+ *
226
+ * This API allows applications to fetch content from external URLs through the platform's
227
+ * proxy service, which handles authentication, caching, bandwidth quotas, and CORS issues.
228
+ * The proxy is useful for accessing external APIs or content that may have CORS restrictions.
229
+ *
230
+ * @returns The Proxy API object
231
+ * @throws {Error} If called before configure() or after destroy()
232
+ * @example
233
+ * // Fetch JSON from an external API
234
+ * const response = await proxy().fetch('https://api.example.com/data');
235
+ * const data = await response.json();
236
+ */
237
+ export declare function proxy(): import("./proxy.js").Proxy;
210
238
  /**
211
239
  * Provides access to the root settings navigation API for TelemetryOS administration UI integration.
212
240
  *
@@ -222,3 +250,20 @@ export declare function users(): import("./users.js").Users;
222
250
  * @throws {Error} If used by an application not mounted at the 'rootSettingsNavigation' mount point
223
251
  */
224
252
  export declare function rootSettingsNavigation(): import("./root-settings-navigation.js").RootSettingsNavigation;
253
+ /**
254
+ * Provides access to the weather API for retrieving weather information.
255
+ *
256
+ * This API allows applications to fetch current weather conditions and forecasts
257
+ * for specified locations through the TelemetryOS platform's General Integrations Service.
258
+ * It supports multiple weather providers including WeatherBit and AccuWeather.
259
+ *
260
+ * @returns The Weather API object
261
+ * @throws {Error} If called before configure() or after destroy()
262
+ * @example
263
+ * // Get current conditions
264
+ * const conditions = await weather().getConditions({ city: 'New York', units: 'imperial' });
265
+ *
266
+ * // Get daily forecast
267
+ * const forecast = await weather().getDailyForecast({ city: 'London', units: 'metric', days: 5 });
268
+ */
269
+ export declare function weather(): import("./weather.js").Weather;