@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":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAGD,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,gBAAgB,CAAmD;IAC3E,OAAO,CAAC,aAAa,CAAoD;IACzE,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAA2B;
|
|
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';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|