@weave-apps/sdk 0.1.17 → 0.1.19
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/dist/WeaveAppInstanceAPI.d.ts +237 -0
- package/dist/WeaveAppInstanceAPI.d.ts.map +1 -0
- package/dist/WeaveAppInstanceAPI.js +395 -0
- package/dist/WeaveBaseApp.d.ts +29 -0
- package/dist/WeaveBaseApp.d.ts.map +1 -1
- package/dist/WeaveBaseApp.js +35 -0
- package/dist/WeaveDOMAPI.d.ts +58 -1
- package/dist/WeaveDOMAPI.d.ts.map +1 -1
- package/dist/WeaveDOMAPI.js +40 -0
- package/dist/global.d.ts +2 -0
- package/dist/global.d.ts.map +1 -1
- package/dist/global.js +2 -0
- package/package.json +1 -1
- package/scripts/copy-sdk-files.js +1 -0
- package/dist/SidekickAPIClient.d.ts +0 -231
- package/dist/SidekickAPIClient.d.ts.map +0 -1
- package/dist/SidekickAPIClient.js +0 -274
- package/dist/SidekickBaseApp.d.ts +0 -177
- package/dist/SidekickBaseApp.d.ts.map +0 -1
- package/dist/SidekickBaseApp.js +0 -228
- package/dist/SidekickDOMAPI.d.ts +0 -433
- package/dist/SidekickDOMAPI.d.ts.map +0 -1
- package/dist/SidekickDOMAPI.js +0 -620
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sidekick API Client
|
|
3
|
-
*
|
|
4
|
-
* Client-side API for iframe apps to interact with the Sidekick backend
|
|
5
|
-
* through a secure proxy in the sidebar.
|
|
6
|
-
*
|
|
7
|
-
* Apps can call AI services and manage their own app data.
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* API operation types
|
|
11
|
-
*/
|
|
12
|
-
var APIOperation;
|
|
13
|
-
(function (APIOperation) {
|
|
14
|
-
// AI Service
|
|
15
|
-
APIOperation["AI_CHAT"] = "AI_CHAT";
|
|
16
|
-
// App Data Service
|
|
17
|
-
APIOperation["APP_DATA_GET_ALL"] = "APP_DATA_GET_ALL";
|
|
18
|
-
APIOperation["APP_DATA_CREATE"] = "APP_DATA_CREATE";
|
|
19
|
-
APIOperation["APP_DATA_GET"] = "APP_DATA_GET";
|
|
20
|
-
APIOperation["APP_DATA_UPDATE"] = "APP_DATA_UPDATE";
|
|
21
|
-
APIOperation["APP_DATA_DELETE"] = "APP_DATA_DELETE";
|
|
22
|
-
})(APIOperation || (APIOperation = {}));
|
|
23
|
-
/**
|
|
24
|
-
* Sidekick API Client
|
|
25
|
-
* Provides methods for iframe apps to interact with Sidekick backend
|
|
26
|
-
*/
|
|
27
|
-
export class SidekickAPIClient {
|
|
28
|
-
constructor() {
|
|
29
|
-
this.pendingRequests = new Map();
|
|
30
|
-
this.messageListener = null;
|
|
31
|
-
this.requestCounter = 0;
|
|
32
|
-
this.timeout = 180000; // 3 minute timeout for API calls (AI can take time on large forms)
|
|
33
|
-
this.appId = null; // App ID set by the app
|
|
34
|
-
// ============================================================================
|
|
35
|
-
// AI Service
|
|
36
|
-
// ============================================================================
|
|
37
|
-
/**
|
|
38
|
-
* Send a chat message to the AI service
|
|
39
|
-
*
|
|
40
|
-
* Note: App ID is automatically injected by the APIBridge.
|
|
41
|
-
* You only need to provide the prompt and optional context.
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```javascript
|
|
45
|
-
* const response = await sidekickAPI.ai.chat({
|
|
46
|
-
* prompt: 'What is the capital of France?',
|
|
47
|
-
* context: 'User is learning geography'
|
|
48
|
-
* });
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
this.ai = {
|
|
52
|
-
chat: async (request) => {
|
|
53
|
-
return this.sendRequest(APIOperation.AI_CHAT, request);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
// ============================================================================
|
|
57
|
-
// App Data Service
|
|
58
|
-
// ============================================================================
|
|
59
|
-
/**
|
|
60
|
-
* App Data operations - CRUD for app-specific data storage
|
|
61
|
-
*/
|
|
62
|
-
this.appData = {
|
|
63
|
-
/**
|
|
64
|
-
* Get all app data for the current company (paginated)
|
|
65
|
-
*
|
|
66
|
-
* Returns a paginated response with data and metadata.
|
|
67
|
-
* Default limit is 25 items. For apps with large datasets (500-5000+ rows),
|
|
68
|
-
* use pagination to avoid performance issues.
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```javascript
|
|
72
|
-
* // Get first page (default: 25 items)
|
|
73
|
-
* const response = await sidekickAPI.appData.getAll();
|
|
74
|
-
*
|
|
75
|
-
* // Access the array of items
|
|
76
|
-
* const items = response.data;
|
|
77
|
-
* items.forEach(item => {
|
|
78
|
-
* });
|
|
79
|
-
* ```
|
|
80
|
-
*/
|
|
81
|
-
getAll: async () => {
|
|
82
|
-
return this.sendRequest(APIOperation.APP_DATA_GET_ALL, {});
|
|
83
|
-
},
|
|
84
|
-
/**
|
|
85
|
-
* Create new app data
|
|
86
|
-
*
|
|
87
|
-
* Note: App ID is automatically injected by the APIBridge.
|
|
88
|
-
*
|
|
89
|
-
* @example
|
|
90
|
-
* ```javascript
|
|
91
|
-
* const newData = await sidekickAPI.appData.create({
|
|
92
|
-
* dataKey: 'user-preferences',
|
|
93
|
-
* data: { theme: 'dark', language: 'en' }
|
|
94
|
-
* });
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
create: async (request) => {
|
|
98
|
-
return this.sendRequest(APIOperation.APP_DATA_CREATE, request);
|
|
99
|
-
},
|
|
100
|
-
/**
|
|
101
|
-
* Get specific app data by ID
|
|
102
|
-
*
|
|
103
|
-
* @example
|
|
104
|
-
* ```javascript
|
|
105
|
-
* const data = await sidekickAPI.appData.get('data-id-123');
|
|
106
|
-
* ```
|
|
107
|
-
*/
|
|
108
|
-
get: async (appDataId) => {
|
|
109
|
-
return this.sendRequest(APIOperation.APP_DATA_GET, { appDataId });
|
|
110
|
-
},
|
|
111
|
-
/**
|
|
112
|
-
* Update existing app data
|
|
113
|
-
*
|
|
114
|
-
* @example
|
|
115
|
-
* ```javascript
|
|
116
|
-
* const updated = await sidekickAPI.appData.update('data-id-123', {
|
|
117
|
-
* data: { theme: 'light' }
|
|
118
|
-
* });
|
|
119
|
-
* ```
|
|
120
|
-
*/
|
|
121
|
-
update: async (appDataId, request) => {
|
|
122
|
-
return this.sendRequest(APIOperation.APP_DATA_UPDATE, {
|
|
123
|
-
appDataId,
|
|
124
|
-
...request
|
|
125
|
-
});
|
|
126
|
-
},
|
|
127
|
-
/**
|
|
128
|
-
* Delete app data
|
|
129
|
-
*
|
|
130
|
-
* @example
|
|
131
|
-
* ```javascript
|
|
132
|
-
* await sidekickAPI.appData.delete('data-id-123');
|
|
133
|
-
* ```
|
|
134
|
-
*/
|
|
135
|
-
delete: async (appDataId) => {
|
|
136
|
-
return this.sendRequest(APIOperation.APP_DATA_DELETE, { appDataId });
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
/**
|
|
140
|
-
* Utility functions for common operations
|
|
141
|
-
*
|
|
142
|
-
* Note: These utilities are loaded from the sidebar-loader at runtime.
|
|
143
|
-
* They are available through the window object and don't need to be bundled with apps.
|
|
144
|
-
*/
|
|
145
|
-
this.utils = {
|
|
146
|
-
/**
|
|
147
|
-
* Convert HTML to Markdown
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```javascript
|
|
151
|
-
* const markdown = sidekickAPI.utils.htmlToMarkdown('<h1>Hello</h1>');
|
|
152
|
-
* console.log(markdown); // # Hello
|
|
153
|
-
* ```
|
|
154
|
-
*/
|
|
155
|
-
htmlToMarkdown: (html) => {
|
|
156
|
-
// Access the utility from window object (loaded by sidebar-loader)
|
|
157
|
-
if (typeof window !== 'undefined' && window.__sidekickUtils?.htmlToMarkdown) {
|
|
158
|
-
return window.__sidekickUtils.htmlToMarkdown(html);
|
|
159
|
-
}
|
|
160
|
-
throw new Error('htmlToMarkdown utility not available. Ensure sidebar-loader is loaded.');
|
|
161
|
-
},
|
|
162
|
-
/**
|
|
163
|
-
* Convert Markdown to HTML (sanitized)
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* ```javascript
|
|
167
|
-
* const html = sidekickAPI.utils.markdownToHtml('# Hello');
|
|
168
|
-
* console.log(html); // <h1>Hello</h1>
|
|
169
|
-
* ```
|
|
170
|
-
*/
|
|
171
|
-
markdownToHtml: (markdown) => {
|
|
172
|
-
// Access the utility from window object (loaded by sidebar-loader)
|
|
173
|
-
if (typeof window !== 'undefined' && window.__sidekickUtils?.markdownToHtml) {
|
|
174
|
-
return window.__sidekickUtils.markdownToHtml(markdown);
|
|
175
|
-
}
|
|
176
|
-
throw new Error('markdownToHtml utility not available. Ensure sidebar-loader is loaded.');
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
this.initialize();
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Set the app ID for this client
|
|
183
|
-
* Called automatically by SidekickBaseApp
|
|
184
|
-
*/
|
|
185
|
-
setAppId(appId) {
|
|
186
|
-
this.appId = appId;
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Initialize the API client and start listening for responses
|
|
190
|
-
*/
|
|
191
|
-
initialize() {
|
|
192
|
-
this.messageListener = (event) => {
|
|
193
|
-
this.handleResponse(event);
|
|
194
|
-
};
|
|
195
|
-
window.addEventListener('message', this.messageListener);
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Cleanup
|
|
199
|
-
*/
|
|
200
|
-
destroy() {
|
|
201
|
-
if (this.messageListener) {
|
|
202
|
-
window.removeEventListener('message', this.messageListener);
|
|
203
|
-
this.messageListener = null;
|
|
204
|
-
}
|
|
205
|
-
this.pendingRequests.clear();
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Handle response from sidebar
|
|
209
|
-
*/
|
|
210
|
-
handleResponse(event) {
|
|
211
|
-
const data = event.data;
|
|
212
|
-
if (data?.type !== 'SIDEKICK_API_RESPONSE') {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
const response = data;
|
|
216
|
-
const pending = this.pendingRequests.get(response.id);
|
|
217
|
-
if (!pending) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
this.pendingRequests.delete(response.id);
|
|
221
|
-
if (response.success) {
|
|
222
|
-
pending.resolve(response.data);
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
pending.reject(new Error(response.error || 'Unknown error'));
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Send request to sidebar
|
|
230
|
-
*/
|
|
231
|
-
sendRequest(operation, payload) {
|
|
232
|
-
return new Promise((resolve, reject) => {
|
|
233
|
-
const id = `api-request-${++this.requestCounter}`;
|
|
234
|
-
const request = {
|
|
235
|
-
type: 'SIDEKICK_API_REQUEST',
|
|
236
|
-
id,
|
|
237
|
-
operation,
|
|
238
|
-
payload,
|
|
239
|
-
appId: this.appId || undefined, // Include app ID if set
|
|
240
|
-
};
|
|
241
|
-
// Store pending request
|
|
242
|
-
this.pendingRequests.set(id, { resolve, reject });
|
|
243
|
-
// Set timeout
|
|
244
|
-
const timeoutId = setTimeout(() => {
|
|
245
|
-
this.pendingRequests.delete(id);
|
|
246
|
-
reject(new Error(`Request timeout: ${operation}`));
|
|
247
|
-
}, this.timeout);
|
|
248
|
-
// Clear timeout on resolve/reject
|
|
249
|
-
const originalResolve = resolve;
|
|
250
|
-
const originalReject = reject;
|
|
251
|
-
this.pendingRequests.set(id, {
|
|
252
|
-
resolve: (value) => {
|
|
253
|
-
clearTimeout(timeoutId);
|
|
254
|
-
originalResolve(value);
|
|
255
|
-
},
|
|
256
|
-
reject: (error) => {
|
|
257
|
-
clearTimeout(timeoutId);
|
|
258
|
-
originalReject(error);
|
|
259
|
-
},
|
|
260
|
-
});
|
|
261
|
-
// Send to current window (sidebar APIBridge will intercept)
|
|
262
|
-
// Apps run in the sidebar's window, not in a separate iframe
|
|
263
|
-
window.postMessage(request, '*');
|
|
264
|
-
APIOperation;
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
// Create singleton instance
|
|
269
|
-
const sidekickAPI = new SidekickAPIClient();
|
|
270
|
-
// Export for global usage
|
|
271
|
-
if (typeof window !== 'undefined') {
|
|
272
|
-
window.sidekickAPI = sidekickAPI;
|
|
273
|
-
}
|
|
274
|
-
export default sidekickAPI;
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sidekick Base App
|
|
3
|
-
*
|
|
4
|
-
* Base class for all Sidekick apps. Provides common functionality and lifecycle methods.
|
|
5
|
-
* Third-party developers should extend this class instead of HTMLElement directly.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```typescript
|
|
9
|
-
* // Define your settings and state types
|
|
10
|
-
* interface MyAppSettings {
|
|
11
|
-
* apiKey: string;
|
|
12
|
-
* endpoint: string;
|
|
13
|
-
* autoSave?: boolean;
|
|
14
|
-
* }
|
|
15
|
-
*
|
|
16
|
-
* interface MyAppState {
|
|
17
|
-
* count: number;
|
|
18
|
-
* isLoading: boolean;
|
|
19
|
-
* data: any[];
|
|
20
|
-
* }
|
|
21
|
-
*
|
|
22
|
-
* class MyApp extends SidekickBaseApp<MyAppSettings, MyAppState> {
|
|
23
|
-
* constructor() {
|
|
24
|
-
* super({
|
|
25
|
-
* id: 'my-app',
|
|
26
|
-
* name: 'My App',
|
|
27
|
-
* version: '1.0.0',
|
|
28
|
-
* category: 'utility',
|
|
29
|
-
* description: 'My custom app',
|
|
30
|
-
* author: 'Your Name',
|
|
31
|
-
* tags: ['custom']
|
|
32
|
-
* });
|
|
33
|
-
*
|
|
34
|
-
* // Settings are now type-safe!
|
|
35
|
-
* const apiKey = this.appSettings?.apiKey; // ✅ TypeScript knows this exists
|
|
36
|
-
*
|
|
37
|
-
* // Initialize state with proper typing
|
|
38
|
-
* this.state = {
|
|
39
|
-
* count: 0,
|
|
40
|
-
* isLoading: false,
|
|
41
|
-
* data: []
|
|
42
|
-
* };
|
|
43
|
-
* }
|
|
44
|
-
*
|
|
45
|
-
* render() {
|
|
46
|
-
* return `<div>My App Content</div>`;
|
|
47
|
-
* }
|
|
48
|
-
*
|
|
49
|
-
* setupEventListeners() {
|
|
50
|
-
* // setState is also type-safe
|
|
51
|
-
* this.setState({ count: this.state.count + 1 }); // ✅ Type-safe
|
|
52
|
-
* }
|
|
53
|
-
* }
|
|
54
|
-
*
|
|
55
|
-
* customElements.define('my-app', MyApp);
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
/**
|
|
59
|
-
* App metadata configuration
|
|
60
|
-
*/
|
|
61
|
-
export interface SidekickAppInfo {
|
|
62
|
-
/** Unique identifier for the app (kebab-case recommended) */
|
|
63
|
-
id: string;
|
|
64
|
-
/** Display name of the app */
|
|
65
|
-
name: string;
|
|
66
|
-
/** Semantic version (x.y.z) */
|
|
67
|
-
version: string;
|
|
68
|
-
/** Primary category for the app */
|
|
69
|
-
category: string;
|
|
70
|
-
/** Detailed description of the app */
|
|
71
|
-
description: string;
|
|
72
|
-
/** Author or organization name */
|
|
73
|
-
author: string;
|
|
74
|
-
/** Additional tags for search and categorization */
|
|
75
|
-
tags?: string[];
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Base class for Sidekick apps
|
|
79
|
-
* @template TSettings - Type for app settings, defaults to an empty object
|
|
80
|
-
* @template TState - Type for app state, defaults to an empty object
|
|
81
|
-
*/
|
|
82
|
-
export declare abstract class SidekickBaseApp<TSettings = Record<string, any>, TState = Record<string, any>> extends HTMLElement {
|
|
83
|
-
/** App metadata */
|
|
84
|
-
protected appInfo: SidekickAppInfo;
|
|
85
|
-
/** App settings (override in subclass) **/
|
|
86
|
-
protected appSettings?: TSettings;
|
|
87
|
-
/** App-specific state (override in subclass) */
|
|
88
|
-
protected state: TState;
|
|
89
|
-
/** Shadow root for style isolation */
|
|
90
|
-
private _shadowRoot;
|
|
91
|
-
/** App-specific API client instance (prevents app ID conflicts) */
|
|
92
|
-
protected sidekickAPI: any;
|
|
93
|
-
/**
|
|
94
|
-
* Creates a new Sidekick app
|
|
95
|
-
* @param appInfo - App metadata configuration
|
|
96
|
-
*/
|
|
97
|
-
constructor(appInfo: SidekickAppInfo);
|
|
98
|
-
/**
|
|
99
|
-
* Get shadow root (override native property)
|
|
100
|
-
*/
|
|
101
|
-
get shadowRoot(): ShadowRoot;
|
|
102
|
-
/**
|
|
103
|
-
* Background service - optional override in subclass
|
|
104
|
-
* Called immediately after app instantiation, before DOM attachment
|
|
105
|
-
* Use this for background tasks like URL monitoring, event listening, etc.
|
|
106
|
-
*/
|
|
107
|
-
protected onBackgroundService?(): void;
|
|
108
|
-
/**
|
|
109
|
-
* URL change handler - optional override in subclass
|
|
110
|
-
* Called when the page URL changes (SPA navigation)
|
|
111
|
-
* @param url - The new URL
|
|
112
|
-
*/
|
|
113
|
-
protected onUrlChange?(url: string): void;
|
|
114
|
-
/**
|
|
115
|
-
* Render method - must be implemented by subclass
|
|
116
|
-
* Should return HTML string or directly manipulate shadowRoot
|
|
117
|
-
*/
|
|
118
|
-
protected render(): void;
|
|
119
|
-
/**
|
|
120
|
-
* Setup event listeners - optional override in subclass
|
|
121
|
-
*/
|
|
122
|
-
protected setupEventListeners(): void;
|
|
123
|
-
/**
|
|
124
|
-
* Initialize background service
|
|
125
|
-
* Called by BackgroundAppManager after instantiation
|
|
126
|
-
*/
|
|
127
|
-
initializeBackgroundService(): void;
|
|
128
|
-
/**
|
|
129
|
-
* Handle URL change
|
|
130
|
-
* Called by BackgroundAppManager when URL changes
|
|
131
|
-
*/
|
|
132
|
-
handleUrlChange(url: string): void;
|
|
133
|
-
/**
|
|
134
|
-
* Lifecycle: Called when element is added to DOM
|
|
135
|
-
* This happens when user opens the app in the drawer
|
|
136
|
-
*/
|
|
137
|
-
connectedCallback(): void;
|
|
138
|
-
/**
|
|
139
|
-
* Lifecycle: Called when element is removed from DOM
|
|
140
|
-
*/
|
|
141
|
-
disconnectedCallback(): void;
|
|
142
|
-
/**
|
|
143
|
-
* Cleanup method - optional override in subclass
|
|
144
|
-
* Called when app is disconnected from DOM
|
|
145
|
-
*/
|
|
146
|
-
protected cleanup(): void;
|
|
147
|
-
/**
|
|
148
|
-
* Get app configuration (for Sidekick Platform)
|
|
149
|
-
*/
|
|
150
|
-
getAppInfo(): SidekickAppInfo;
|
|
151
|
-
/**
|
|
152
|
-
* Get current app state (for Sidekick Platform)
|
|
153
|
-
*/
|
|
154
|
-
getAppState(): Record<string, any>;
|
|
155
|
-
/**
|
|
156
|
-
* Set app configuration (for Sidekick Platform)
|
|
157
|
-
* Override this method to handle configuration updates
|
|
158
|
-
*/
|
|
159
|
-
setAppConfig(_config: Record<string, any>): void;
|
|
160
|
-
/**
|
|
161
|
-
* Helper: Update app state
|
|
162
|
-
*/
|
|
163
|
-
protected setState(updates: Partial<TState>): void;
|
|
164
|
-
/**
|
|
165
|
-
* Helper: Render HTML into shadow root
|
|
166
|
-
*/
|
|
167
|
-
protected renderHTML(html: string): void;
|
|
168
|
-
/**
|
|
169
|
-
* Helper: Query element in shadow root
|
|
170
|
-
*/
|
|
171
|
-
protected query<T extends Element = Element>(selector: string): T | null;
|
|
172
|
-
/**
|
|
173
|
-
* Helper: Query all elements in shadow root
|
|
174
|
-
*/
|
|
175
|
-
protected queryAll<T extends Element = Element>(selector: string): NodeListOf<T>;
|
|
176
|
-
}
|
|
177
|
-
//# sourceMappingURL=SidekickBaseApp.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SidekickBaseApp.d.ts","sourceRoot":"","sources":["../src/SidekickBaseApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,8BAAsB,eAAe,CACnC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAC5B,SAAQ,WAAW;IACnB,mBAAmB;IACnB,SAAS,CAAC,OAAO,EAAE,eAAe,CAAC;IAEnC,2CAA2C;IAC3C,SAAS,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IAElC,gDAAgD;IAChD,SAAS,CAAC,KAAK,EAAE,MAAM,CAAgB;IAEvC,sCAAsC;IACtC,OAAO,CAAC,WAAW,CAAa;IAEhC,mEAAmE;IACnE,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC;IAE3B;;;OAGG;gBACS,OAAO,EAAE,eAAe;IAyCpC;;OAEG;IACH,IAAI,UAAU,IAAI,UAAU,CAE3B;IAED;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,CAAC,IAAI,IAAI;IAEtC;;;;OAIG;IACH,SAAS,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAEzC;;;OAGG;IACH,SAAS,CAAC,MAAM,IAAI,IAAI;IAIxB;;OAEG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAIrC;;;OAGG;IACI,2BAA2B,IAAI,IAAI;IAO1C;;;OAGG;IACI,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMzC;;;OAGG;IACH,iBAAiB,IAAI,IAAI;IAoBzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAI5B;;;OAGG;IACH,SAAS,CAAC,OAAO,IAAI,IAAI;IAIzB;;OAEG;IACI,UAAU,IAAI,eAAe;IAIpC;;OAEG;IACI,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAOzC;;;OAGG;IACI,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAIvD;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAIlD;;OAEG;IACH,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQxC;;OAEG;IACH,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAIxE;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;CAGjF"}
|
package/dist/SidekickBaseApp.js
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sidekick Base App
|
|
3
|
-
*
|
|
4
|
-
* Base class for all Sidekick apps. Provides common functionality and lifecycle methods.
|
|
5
|
-
* Third-party developers should extend this class instead of HTMLElement directly.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```typescript
|
|
9
|
-
* // Define your settings and state types
|
|
10
|
-
* interface MyAppSettings {
|
|
11
|
-
* apiKey: string;
|
|
12
|
-
* endpoint: string;
|
|
13
|
-
* autoSave?: boolean;
|
|
14
|
-
* }
|
|
15
|
-
*
|
|
16
|
-
* interface MyAppState {
|
|
17
|
-
* count: number;
|
|
18
|
-
* isLoading: boolean;
|
|
19
|
-
* data: any[];
|
|
20
|
-
* }
|
|
21
|
-
*
|
|
22
|
-
* class MyApp extends SidekickBaseApp<MyAppSettings, MyAppState> {
|
|
23
|
-
* constructor() {
|
|
24
|
-
* super({
|
|
25
|
-
* id: 'my-app',
|
|
26
|
-
* name: 'My App',
|
|
27
|
-
* version: '1.0.0',
|
|
28
|
-
* category: 'utility',
|
|
29
|
-
* description: 'My custom app',
|
|
30
|
-
* author: 'Your Name',
|
|
31
|
-
* tags: ['custom']
|
|
32
|
-
* });
|
|
33
|
-
*
|
|
34
|
-
* // Settings are now type-safe!
|
|
35
|
-
* const apiKey = this.appSettings?.apiKey; // ✅ TypeScript knows this exists
|
|
36
|
-
*
|
|
37
|
-
* // Initialize state with proper typing
|
|
38
|
-
* this.state = {
|
|
39
|
-
* count: 0,
|
|
40
|
-
* isLoading: false,
|
|
41
|
-
* data: []
|
|
42
|
-
* };
|
|
43
|
-
* }
|
|
44
|
-
*
|
|
45
|
-
* render() {
|
|
46
|
-
* return `<div>My App Content</div>`;
|
|
47
|
-
* }
|
|
48
|
-
*
|
|
49
|
-
* setupEventListeners() {
|
|
50
|
-
* // setState is also type-safe
|
|
51
|
-
* this.setState({ count: this.state.count + 1 }); // ✅ Type-safe
|
|
52
|
-
* }
|
|
53
|
-
* }
|
|
54
|
-
*
|
|
55
|
-
* customElements.define('my-app', MyApp);
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
/**
|
|
59
|
-
* Base class for Sidekick apps
|
|
60
|
-
* @template TSettings - Type for app settings, defaults to an empty object
|
|
61
|
-
* @template TState - Type for app state, defaults to an empty object
|
|
62
|
-
*/
|
|
63
|
-
export class SidekickBaseApp extends HTMLElement {
|
|
64
|
-
/**
|
|
65
|
-
* Creates a new Sidekick app
|
|
66
|
-
* @param appInfo - App metadata configuration
|
|
67
|
-
*/
|
|
68
|
-
constructor(appInfo) {
|
|
69
|
-
super();
|
|
70
|
-
/** App-specific state (override in subclass) */
|
|
71
|
-
this.state = {};
|
|
72
|
-
// Validate required fields
|
|
73
|
-
if (!appInfo.id || !appInfo.name || !appInfo.version) {
|
|
74
|
-
throw new Error('SidekickBaseApp: id, name, and version are required');
|
|
75
|
-
}
|
|
76
|
-
this.appInfo = appInfo;
|
|
77
|
-
// Create shadow DOM for style isolation and store reference
|
|
78
|
-
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
|
79
|
-
// Read UUID and settings from global registry (set by BackgroundAppManager before element creation)
|
|
80
|
-
// This allows the constructor to access both UUID and settings immediately
|
|
81
|
-
const registry = window.__sidekickAppRegistry;
|
|
82
|
-
const tagName = this.tagName.toLowerCase();
|
|
83
|
-
const registryData = registry?.[tagName];
|
|
84
|
-
// Set app settings if available in registry
|
|
85
|
-
if (registryData?.settings) {
|
|
86
|
-
this.appSettings = registryData.settings;
|
|
87
|
-
}
|
|
88
|
-
// Set app UUID on the global API client so it's included in all requests
|
|
89
|
-
// This allows background services to make API calls without the app being open
|
|
90
|
-
if (window.sidekickAPI) {
|
|
91
|
-
const appUuid = registryData?.uuid;
|
|
92
|
-
if (appUuid) {
|
|
93
|
-
// Create a new API client instance for THIS app
|
|
94
|
-
this.sidekickAPI = new window.SidekickAPIClient();
|
|
95
|
-
this.sidekickAPI.setAppId(appUuid);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
console.warn('⚠️ App UUID not found in registry - API calls may fail. App:', appInfo.id);
|
|
99
|
-
// Fallback to global API client (will have wrong app ID, but better than nothing)
|
|
100
|
-
this.sidekickAPI = window.sidekickAPI;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Get shadow root (override native property)
|
|
106
|
-
*/
|
|
107
|
-
get shadowRoot() {
|
|
108
|
-
return this._shadowRoot;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Render method - must be implemented by subclass
|
|
112
|
-
* Should return HTML string or directly manipulate shadowRoot
|
|
113
|
-
*/
|
|
114
|
-
render() {
|
|
115
|
-
// Default implementation - subclasses should override
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Setup event listeners - optional override in subclass
|
|
119
|
-
*/
|
|
120
|
-
setupEventListeners() {
|
|
121
|
-
// Default implementation - subclasses can override
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Initialize background service
|
|
125
|
-
* Called by BackgroundAppManager after instantiation
|
|
126
|
-
*/
|
|
127
|
-
initializeBackgroundService() {
|
|
128
|
-
if (this.onBackgroundService) {
|
|
129
|
-
this.onBackgroundService();
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Handle URL change
|
|
134
|
-
* Called by BackgroundAppManager when URL changes
|
|
135
|
-
*/
|
|
136
|
-
handleUrlChange(url) {
|
|
137
|
-
if (this.onUrlChange) {
|
|
138
|
-
this.onUrlChange(url);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Lifecycle: Called when element is added to DOM
|
|
143
|
-
* This happens when user opens the app in the drawer
|
|
144
|
-
*/
|
|
145
|
-
connectedCallback() {
|
|
146
|
-
// Render the app UI
|
|
147
|
-
this.render();
|
|
148
|
-
// Setup event listeners for UI
|
|
149
|
-
this.setupEventListeners();
|
|
150
|
-
// Notify Sidekick Platform that app UI is ready
|
|
151
|
-
this.dispatchEvent(new CustomEvent('sidekick-app-ready', {
|
|
152
|
-
detail: {
|
|
153
|
-
appInfo: this.appInfo,
|
|
154
|
-
timestamp: new Date().toISOString()
|
|
155
|
-
},
|
|
156
|
-
bubbles: true,
|
|
157
|
-
composed: true
|
|
158
|
-
}));
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Lifecycle: Called when element is removed from DOM
|
|
162
|
-
*/
|
|
163
|
-
disconnectedCallback() {
|
|
164
|
-
this.cleanup();
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Cleanup method - optional override in subclass
|
|
168
|
-
* Called when app is disconnected from DOM
|
|
169
|
-
*/
|
|
170
|
-
cleanup() {
|
|
171
|
-
// Default implementation - subclasses can override
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Get app configuration (for Sidekick Platform)
|
|
175
|
-
*/
|
|
176
|
-
getAppInfo() {
|
|
177
|
-
return this.appInfo;
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Get current app state (for Sidekick Platform)
|
|
181
|
-
*/
|
|
182
|
-
getAppState() {
|
|
183
|
-
return {
|
|
184
|
-
...this.state,
|
|
185
|
-
lastUpdated: new Date().toISOString()
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Set app configuration (for Sidekick Platform)
|
|
190
|
-
* Override this method to handle configuration updates
|
|
191
|
-
*/
|
|
192
|
-
setAppConfig(_config) {
|
|
193
|
-
// Default implementation - subclasses can override
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Helper: Update app state
|
|
197
|
-
*/
|
|
198
|
-
setState(updates) {
|
|
199
|
-
this.state = { ...this.state, ...updates };
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Helper: Render HTML into shadow root
|
|
203
|
-
*/
|
|
204
|
-
renderHTML(html) {
|
|
205
|
-
if (this._shadowRoot) {
|
|
206
|
-
this._shadowRoot.innerHTML = html;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
console.error('❌ No shadow root available!');
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Helper: Query element in shadow root
|
|
214
|
-
*/
|
|
215
|
-
query(selector) {
|
|
216
|
-
return this._shadowRoot?.querySelector(selector) || null;
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Helper: Query all elements in shadow root
|
|
220
|
-
*/
|
|
221
|
-
queryAll(selector) {
|
|
222
|
-
return this._shadowRoot?.querySelectorAll(selector) || [];
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
// Export for global usage
|
|
226
|
-
if (typeof window !== 'undefined') {
|
|
227
|
-
window.SidekickBaseApp = SidekickBaseApp;
|
|
228
|
-
}
|