@thewhateverapp/tile-sdk 0.8.9 → 0.9.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.
@@ -19,6 +19,13 @@ export interface TileConfig {
19
19
  theme?: 'light' | 'dark';
20
20
  debug?: boolean;
21
21
  }
22
+ /**
23
+ * Tile-scoped token data received from parent
24
+ */
25
+ export interface TileTokenData {
26
+ token: string;
27
+ expiresAt: string;
28
+ }
22
29
  type NextRouter = {
23
30
  push: (href: string) => void;
24
31
  replace: (href: string) => void;
@@ -32,6 +39,8 @@ export declare class TileBridge {
32
39
  private ready;
33
40
  private parentOrigin;
34
41
  private router;
42
+ private currentToken;
43
+ private tokenExpiresAt;
35
44
  constructor(expectedOrigin?: string, router?: NextRouter);
36
45
  private initialize;
37
46
  private handleMessage;
@@ -39,6 +48,10 @@ export declare class TileBridge {
39
48
  private handleResponse;
40
49
  private handleEvent;
41
50
  private handleParentNavigate;
51
+ /**
52
+ * Handle token message from parent
53
+ */
54
+ private handleToken;
42
55
  private sendToParent;
43
56
  /**
44
57
  * Request to navigate to full page view
@@ -103,8 +116,18 @@ export declare class TileBridge {
103
116
  * Get current authenticated user (if available)
104
117
  */
105
118
  getCurrentUser(): Promise<any>;
119
+ /**
120
+ * Generate a placeholder image for preview mode
121
+ * Creates a simple colored rectangle with text as base64 PNG
122
+ */
123
+ private generateMockImage;
124
+ /**
125
+ * Generate a mock file for preview mode
126
+ */
127
+ private generateMockFile;
106
128
  /**
107
129
  * Capture a photo from camera or device library
130
+ * In preview mode, returns a mock placeholder image
108
131
  * @param options - Capture options (quality, maxSize, source, etc.)
109
132
  * @returns Promise resolving to MediaFile with base64 data
110
133
  */
@@ -124,6 +147,7 @@ export declare class TileBridge {
124
147
  }>;
125
148
  /**
126
149
  * Select a file from device
150
+ * In preview mode, returns a mock placeholder file
127
151
  * @param options - File selection options (accept, maxSize, etc.)
128
152
  * @returns Promise resolving to MediaFile with base64 data
129
153
  */
@@ -140,6 +164,7 @@ export declare class TileBridge {
140
164
  }>;
141
165
  /**
142
166
  * Select multiple files from device
167
+ * In preview mode, returns mock placeholder files
143
168
  * @param options - File selection options (accept, maxSize, maxFiles, etc.)
144
169
  * @returns Promise resolving to array of MediaFile with base64 data
145
170
  */
@@ -167,6 +192,34 @@ export declare class TileBridge {
167
192
  * Check if ready
168
193
  */
169
194
  isReady(): boolean;
195
+ /**
196
+ * Get the current tile-scoped token
197
+ * Returns null if no token has been received from parent
198
+ */
199
+ getToken(): string | null;
200
+ /**
201
+ * Get the current token data (token + expiry)
202
+ * Returns null if no token has been received
203
+ */
204
+ getTokenData(): TileTokenData | null;
205
+ /**
206
+ * Check if the current token is valid (exists and not expired)
207
+ */
208
+ hasValidToken(): boolean;
209
+ /**
210
+ * Wait for a valid token to be received
211
+ * Useful when tile needs to perform authenticated operations immediately
212
+ * @param timeoutMs Maximum time to wait (default: 10 seconds)
213
+ */
214
+ waitForToken(timeoutMs?: number): Promise<string | null>;
215
+ /**
216
+ * Subscribe to token updates
217
+ * Called when parent sends a new or refreshed token
218
+ */
219
+ onTokenUpdate(handler: (data: {
220
+ token: string;
221
+ expiresAt: Date;
222
+ }) => void): () => void;
170
223
  /**
171
224
  * Wait for ready state
172
225
  *
@@ -1 +1 @@
1
- {"version":3,"file":"TileBridge.d.ts","sourceRoot":"","sources":["../../src/bridge/TileBridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TileBridge.d.ts","sourceRoot":"","sources":["../../src/bridge/TileBridge.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,9 @@ export class TileBridge {
10
10
  this.eventHandlers = new Map();
11
11
  this.ready = false;
12
12
  this.router = null;
13
+ // Tile-scoped token state
14
+ this.currentToken = null;
15
+ this.tokenExpiresAt = null;
13
16
  this.parentOrigin = expectedOrigin;
14
17
  this.router = router || null;
15
18
  // Auto-detect parent origin based on environment
@@ -90,6 +93,9 @@ export class TileBridge {
90
93
  case 'parent:navigate':
91
94
  this.handleParentNavigate(message.payload);
92
95
  break;
96
+ case 'parent:token':
97
+ this.handleToken(message.payload);
98
+ break;
93
99
  case 'parent:navigateToPage':
94
100
  this.handleParentNavigate({ target: 'page' });
95
101
  break;
@@ -144,6 +150,28 @@ export class TileBridge {
144
150
  }
145
151
  }
146
152
  }
153
+ /**
154
+ * Handle token message from parent
155
+ */
156
+ handleToken(payload) {
157
+ if (!payload?.token || !payload?.expiresAt) {
158
+ console.warn('[TileBridge] Invalid token payload received');
159
+ return;
160
+ }
161
+ this.currentToken = payload.token;
162
+ this.tokenExpiresAt = new Date(payload.expiresAt);
163
+ if (this.isDevelopment() || this.isPreview()) {
164
+ console.log('[TileBridge] 🔑 Received tile token', {
165
+ tokenPrefix: payload.token.substring(0, 20) + '...',
166
+ expiresAt: this.tokenExpiresAt.toISOString(),
167
+ });
168
+ }
169
+ // Emit token update event for listeners
170
+ this.emitEvent('token:update', {
171
+ token: this.currentToken,
172
+ expiresAt: this.tokenExpiresAt,
173
+ });
174
+ }
147
175
  sendToParent(message) {
148
176
  if (typeof window === 'undefined' || !window.parent)
149
177
  return;
@@ -497,12 +525,72 @@ export class TileBridge {
497
525
  });
498
526
  }
499
527
  // ============= MEDIA CAPTURE API =============
528
+ /**
529
+ * Generate a placeholder image for preview mode
530
+ * Creates a simple colored rectangle with text as base64 PNG
531
+ */
532
+ generateMockImage(width = 400, height = 300) {
533
+ // Create a simple SVG placeholder that can be used as a data URL
534
+ // This works in browser environments without canvas
535
+ const colors = ['#4A90A4', '#7B68EE', '#20B2AA', '#FF6B6B', '#4ECDC4', '#45B7D1'];
536
+ const color = colors[Math.floor(Math.random() * colors.length)];
537
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
538
+ <rect width="${width}" height="${height}" fill="${color}"/>
539
+ <rect x="10" y="10" width="${width - 20}" height="${height - 20}" fill="none" stroke="white" stroke-width="2" stroke-dasharray="10,5" rx="10"/>
540
+ <text x="${width / 2}" y="${height / 2 - 20}" font-family="Arial, sans-serif" font-size="24" fill="white" text-anchor="middle">📷</text>
541
+ <text x="${width / 2}" y="${height / 2 + 15}" font-family="Arial, sans-serif" font-size="16" fill="white" text-anchor="middle">Preview Mode</text>
542
+ <text x="${width / 2}" y="${height / 2 + 40}" font-family="Arial, sans-serif" font-size="12" fill="rgba(255,255,255,0.7)" text-anchor="middle">Camera capture simulated</text>
543
+ </svg>`;
544
+ // Convert SVG to base64
545
+ const base64 = typeof btoa !== 'undefined'
546
+ ? btoa(unescape(encodeURIComponent(svg)))
547
+ : Buffer.from(svg).toString('base64');
548
+ return {
549
+ base64: `data:image/svg+xml;base64,${base64}`,
550
+ mimeType: 'image/svg+xml',
551
+ filename: `preview-photo-${Date.now()}.svg`,
552
+ size: svg.length,
553
+ width,
554
+ height,
555
+ };
556
+ }
557
+ /**
558
+ * Generate a mock file for preview mode
559
+ */
560
+ generateMockFile(accept) {
561
+ // If accepting images, return a mock image
562
+ if (!accept || accept.includes('image') || accept === '*/*') {
563
+ return this.generateMockImage();
564
+ }
565
+ // For other file types, return a simple text/json placeholder
566
+ const mockContent = JSON.stringify({
567
+ preview: true,
568
+ message: 'This is mock file content for preview mode',
569
+ timestamp: new Date().toISOString(),
570
+ }, null, 2);
571
+ const base64 = typeof btoa !== 'undefined'
572
+ ? btoa(mockContent)
573
+ : Buffer.from(mockContent).toString('base64');
574
+ return {
575
+ base64,
576
+ mimeType: 'application/json',
577
+ filename: `preview-file-${Date.now()}.json`,
578
+ size: mockContent.length,
579
+ };
580
+ }
500
581
  /**
501
582
  * Capture a photo from camera or device library
583
+ * In preview mode, returns a mock placeholder image
502
584
  * @param options - Capture options (quality, maxSize, source, etc.)
503
585
  * @returns Promise resolving to MediaFile with base64 data
504
586
  */
505
587
  async capturePhoto(options) {
588
+ // In preview mode, return mock image immediately
589
+ if (this.isPreview()) {
590
+ console.log('[TileBridge] 📸 Preview mode - returning mock photo');
591
+ const mockImage = this.generateMockImage(options?.maxWidth ?? 400, options?.maxHeight ?? 300);
592
+ return Promise.resolve(mockImage);
593
+ }
506
594
  return new Promise((resolve, reject) => {
507
595
  const id = this.generateId();
508
596
  this.responseHandlers.set(id, (response) => {
@@ -538,10 +626,16 @@ export class TileBridge {
538
626
  }
539
627
  /**
540
628
  * Select a file from device
629
+ * In preview mode, returns a mock placeholder file
541
630
  * @param options - File selection options (accept, maxSize, etc.)
542
631
  * @returns Promise resolving to MediaFile with base64 data
543
632
  */
544
633
  async selectFile(options) {
634
+ // In preview mode, return mock file immediately
635
+ if (this.isPreview()) {
636
+ console.log('[TileBridge] 📁 Preview mode - returning mock file');
637
+ return Promise.resolve(this.generateMockFile(options?.accept));
638
+ }
545
639
  return new Promise((resolve, reject) => {
546
640
  const id = this.generateId();
547
641
  this.responseHandlers.set(id, (response) => {
@@ -574,10 +668,18 @@ export class TileBridge {
574
668
  }
575
669
  /**
576
670
  * Select multiple files from device
671
+ * In preview mode, returns mock placeholder files
577
672
  * @param options - File selection options (accept, maxSize, maxFiles, etc.)
578
673
  * @returns Promise resolving to array of MediaFile with base64 data
579
674
  */
580
675
  async selectFiles(options) {
676
+ // In preview mode, return mock files immediately
677
+ if (this.isPreview()) {
678
+ console.log('[TileBridge] 📁📁 Preview mode - returning mock files');
679
+ const count = Math.min(options?.maxFiles ?? 3, 5);
680
+ const files = Array.from({ length: count }, () => this.generateMockFile(options?.accept));
681
+ return Promise.resolve(files);
682
+ }
581
683
  return new Promise((resolve, reject) => {
582
684
  const id = this.generateId();
583
685
  this.responseHandlers.set(id, (response) => {
@@ -637,6 +739,89 @@ export class TileBridge {
637
739
  isReady() {
638
740
  return this.ready;
639
741
  }
742
+ // ============= TILE TOKEN API =============
743
+ /**
744
+ * Get the current tile-scoped token
745
+ * Returns null if no token has been received from parent
746
+ */
747
+ getToken() {
748
+ // Check if token is expired
749
+ if (this.currentToken && this.tokenExpiresAt) {
750
+ if (this.tokenExpiresAt.getTime() < Date.now()) {
751
+ console.warn('[TileBridge] Token expired, returning null');
752
+ return null;
753
+ }
754
+ }
755
+ return this.currentToken;
756
+ }
757
+ /**
758
+ * Get the current token data (token + expiry)
759
+ * Returns null if no token has been received
760
+ */
761
+ getTokenData() {
762
+ if (!this.currentToken || !this.tokenExpiresAt) {
763
+ return null;
764
+ }
765
+ return {
766
+ token: this.currentToken,
767
+ expiresAt: this.tokenExpiresAt.toISOString(),
768
+ };
769
+ }
770
+ /**
771
+ * Check if the current token is valid (exists and not expired)
772
+ */
773
+ hasValidToken() {
774
+ if (!this.currentToken || !this.tokenExpiresAt) {
775
+ return false;
776
+ }
777
+ return this.tokenExpiresAt.getTime() > Date.now();
778
+ }
779
+ /**
780
+ * Wait for a valid token to be received
781
+ * Useful when tile needs to perform authenticated operations immediately
782
+ * @param timeoutMs Maximum time to wait (default: 10 seconds)
783
+ */
784
+ async waitForToken(timeoutMs = 10000) {
785
+ // If we already have a valid token, return immediately
786
+ if (this.hasValidToken()) {
787
+ return this.currentToken;
788
+ }
789
+ return new Promise((resolve) => {
790
+ const startTime = Date.now();
791
+ // Set up listener for token update
792
+ const unsubscribe = this.on('token:update', (data) => {
793
+ if (data?.token) {
794
+ unsubscribe();
795
+ resolve(data.token);
796
+ }
797
+ });
798
+ // Set up timeout
799
+ const checkTimeout = () => {
800
+ if (Date.now() - startTime >= timeoutMs) {
801
+ unsubscribe();
802
+ console.warn('[TileBridge] waitForToken timed out');
803
+ resolve(null);
804
+ return;
805
+ }
806
+ // Check if token arrived
807
+ if (this.hasValidToken()) {
808
+ unsubscribe();
809
+ resolve(this.currentToken);
810
+ return;
811
+ }
812
+ // Keep checking
813
+ setTimeout(checkTimeout, 100);
814
+ };
815
+ checkTimeout();
816
+ });
817
+ }
818
+ /**
819
+ * Subscribe to token updates
820
+ * Called when parent sends a new or refreshed token
821
+ */
822
+ onTokenUpdate(handler) {
823
+ return this.on('token:update', handler);
824
+ }
640
825
  /**
641
826
  * Wait for ready state
642
827
  *
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export { useTileNavigation } from './react/useTileNavigation';
4
4
  export { TileContainer } from './react/TileContainer';
5
5
  export { withTile } from './react/withTile';
6
6
  export { getTileBridge, TileBridge } from './bridge/TileBridge';
7
- export type { TileMessage, TileConfig } from './bridge/TileBridge';
7
+ export type { TileMessage, TileConfig, TileTokenData } from './bridge/TileBridge';
8
8
  export { StateClient } from './state/StateClient';
9
9
  export type { TileStats, ViewResponse } from './state/StateClient';
10
10
  export * from './tools';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnE,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGlF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnE,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thewhateverapp/tile-sdk",
3
- "version": "0.8.9",
3
+ "version": "0.9.1",
4
4
  "description": "SDK for building interactive tiles on The Whatever App platform",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",