@weave-apps/sdk 0.1.5 → 0.1.7

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.
Files changed (2) hide show
  1. package/README.md +313 -52
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -10,6 +10,10 @@ Official SDK for building third-party applications for the Weave Platform.
10
10
  - ✅ **Project Scaffolding** - Quick start with `weave-init`
11
11
  - ✅ **DOM API** - Secure parent page DOM manipulation
12
12
  - ✅ **Shadow DOM Isolation** - Scoped styles and encapsulation
13
+ - ✅ **Background Services** - Run code without user interaction
14
+ - ✅ **Form Integration** - Auto-fill forms with extracted data
15
+ - ✅ **AI Integration** - Leverage AI for smart form filling
16
+ - ✅ **Data Persistence** - Store app data with the Weave API
13
17
 
14
18
  ## Quick Start
15
19
 
@@ -19,6 +23,7 @@ Official SDK for building third-party applications for the Weave Platform.
19
23
  npx weave-init my-custom-app
20
24
  cd my-custom-app
21
25
  npm install
26
+ npm run build
22
27
  ```
23
28
 
24
29
  ### 2. Develop Your App
@@ -26,7 +31,7 @@ npm install
26
31
  Edit `src/app.ts`:
27
32
 
28
33
  ```typescript
29
- import { WeaveBaseApp } from '@weave/app-sdk';
34
+ import { WeaveBaseApp } from '@weave-apps/sdk';
30
35
 
31
36
  class MyCustomApp extends WeaveBaseApp {
32
37
  constructor() {
@@ -39,24 +44,43 @@ class MyCustomApp extends WeaveBaseApp {
39
44
  author: 'Your Name',
40
45
  tags: ['custom']
41
46
  });
47
+
48
+ this.state = {
49
+ count: 0
50
+ };
42
51
  }
43
52
 
44
53
  protected render(): void {
45
54
  this.renderHTML(`
46
55
  <style>
47
- .container { padding: 20px; }
48
- button { padding: 10px 20px; }
56
+ .container {
57
+ padding: 20px;
58
+ font-family: system-ui, sans-serif;
59
+ }
60
+ button {
61
+ padding: 10px 20px;
62
+ background: #3b82f6;
63
+ color: white;
64
+ border: none;
65
+ border-radius: 6px;
66
+ cursor: pointer;
67
+ }
68
+ button:hover {
69
+ background: #2563eb;
70
+ }
49
71
  </style>
50
72
  <div class="container">
51
- <h1>Hello Weave!</h1>
52
- <button id="myBtn">Click Me</button>
73
+ <h1>Counter App</h1>
74
+ <p>Count: <span id="count">${this.state.count}</span></p>
75
+ <button id="incrementBtn">Increment</button>
53
76
  </div>
54
77
  `);
55
78
  }
56
79
 
57
80
  protected setupEventListeners(): void {
58
- this.query('#myBtn')?.addEventListener('click', () => {
59
- alert('Button clicked!');
81
+ this.query('#incrementBtn')?.addEventListener('click', () => {
82
+ this.setState({ count: this.state.count + 1 });
83
+ this.render();
60
84
  });
61
85
  }
62
86
  }
@@ -72,19 +96,19 @@ npm run build
72
96
 
73
97
  This runs:
74
98
  1. `tsc` - Compiles TypeScript to JavaScript
75
- 2. `weave-build` - Transpiles to clean, platform-ready JavaScript
99
+ 2. `weave-compile` - Transpiles to clean, platform-ready JavaScript
76
100
 
77
- Output: `dist/app.js` - ready for upload to Weave Platform.
101
+ Output: `dist/my-custom-app.js` - ready for upload to Weave Platform.
78
102
 
79
103
  ### 4. Upload to Weave
80
104
 
81
- Upload the generated `dist/app.js` file to the Weave Platform via the Enterprise Management Console.
105
+ Upload the generated `dist/my-custom-app.js` file to the Weave Platform via the Enterprise Management Console.
82
106
 
83
107
  ## API Reference
84
108
 
85
109
  ### WeaveBaseApp
86
110
 
87
- Base class for all Weave apps.
111
+ Base class for all Weave apps. Handles state management, rendering, and lifecycle hooks.
88
112
 
89
113
  #### Constructor
90
114
 
@@ -99,53 +123,153 @@ constructor(appInfo: WeaveAppInfo)
99
123
  - `category` (string) - App category
100
124
  - `description` (string) - Detailed description
101
125
  - `author` (string) - Author name
102
- - `tags` (string[]) - Optional tags
126
+ - `tags` (string[])` - Optional tags
127
+
128
+ #### Settings & State
129
+
130
+ Define typed settings and state:
131
+
132
+ ```typescript
133
+ interface MyAppSettings {
134
+ apiEndpoint?: string;
135
+ debugMode?: boolean;
136
+ }
137
+
138
+ interface MyAppState {
139
+ isLoading: boolean;
140
+ data: any;
141
+ }
142
+
143
+ class MyApp extends WeaveBaseApp<MyAppSettings, MyAppState> {
144
+ constructor() {
145
+ super({ /* ... */ });
146
+
147
+ this.state = {
148
+ isLoading: false,
149
+ data: null
150
+ };
151
+
152
+ // Access settings (injected from Enterprise Console)
153
+ console.log(this.appSettings?.apiEndpoint);
154
+ }
155
+ }
156
+ ```
103
157
 
104
158
  #### Methods to Implement
105
159
 
106
- ##### `render(): void`
160
+ ##### `render(): void | Promise<void>`
107
161
  Render your app's UI. Use `this.renderHTML()` to inject HTML.
108
162
 
163
+ ```typescript
164
+ protected async render(): Promise<void> {
165
+ this.renderHTML(`
166
+ <div>Content here</div>
167
+ `);
168
+ }
169
+ ```
170
+
109
171
  ##### `setupEventListeners(): void` (Optional)
110
172
  Setup event listeners for your app's elements.
111
173
 
174
+ ```typescript
175
+ protected setupEventListeners(): void {
176
+ this.query('#myBtn')?.addEventListener('click', () => {
177
+ // Handle click
178
+ });
179
+ }
180
+ ```
181
+
182
+ ##### `onBackgroundService(): void` (Optional)
183
+ Background service that runs when sidebar loads, even if app drawer isn't open.
184
+
185
+ ```typescript
186
+ async onBackgroundService(): Promise<void> {
187
+ const url = await window.weaveDOM.getPageUrl();
188
+ if (url.includes('mypage.com')) {
189
+ // Do something on background
190
+ }
191
+ }
192
+ ```
193
+
194
+ ##### `onUrlChange(newUrl: string): void` (Optional)
195
+ Called when the page URL changes (SPA navigation).
196
+
197
+ ```typescript
198
+ async onUrlChange(newUrl: string): Promise<void> {
199
+ if (newUrl.includes('form')) {
200
+ await this.checkAndInjectButton();
201
+ }
202
+ }
203
+ ```
204
+
112
205
  ##### `cleanup(): void` (Optional)
113
- Cleanup when app is removed from DOM.
206
+ Cleanup when app is removed from DOM. Clear intervals, listeners, watchers.
207
+
208
+ ```typescript
209
+ protected cleanup(): void {
210
+ if (this.myInterval) {
211
+ clearInterval(this.myInterval);
212
+ }
213
+ }
214
+ ```
114
215
 
115
216
  #### Helper Methods
116
217
 
117
218
  ##### `renderHTML(html: string): void`
118
219
  Renders HTML into the shadow root.
119
220
 
221
+ ```typescript
222
+ this.renderHTML('<h1>Hello</h1>');
223
+ ```
224
+
225
+ ##### `setState(updates: object): void`
226
+ Update app state (shallow merge).
227
+
228
+ ```typescript
229
+ this.setState({ isLoading: true, count: 5 });
230
+ ```
231
+
120
232
  ##### `query<T>(selector: string): T | null`
121
233
  Query a single element in shadow root.
122
234
 
235
+ ```typescript
236
+ const btn = this.query<HTMLButtonElement>('#myBtn');
237
+ ```
238
+
123
239
  ##### `queryAll<T>(selector: string): NodeListOf<T>`
124
240
  Query all matching elements in shadow root.
125
241
 
126
- ##### `setState(updates: object): void`
127
- Update app state.
242
+ ```typescript
243
+ const buttons = this.queryAll<HTMLButtonElement>('button');
244
+ ```
128
245
 
129
246
  ### WeaveDOMAPI
130
247
 
131
- API for interacting with the parent page DOM.
248
+ API for securely interacting with the parent page DOM. Available globally as `window.weaveDOM`.
132
249
 
133
- **Available globally as `window.weaveDOM`**
250
+ #### URL & Navigation
251
+
252
+ ```typescript
253
+ // Get current page URL
254
+ const url = await window.weaveDOM.getPageUrl();
255
+
256
+ // Open new tab
257
+ window.open(url, '_blank');
258
+ ```
134
259
 
135
260
  #### Read Operations
136
261
 
137
262
  ```typescript
138
263
  // Query element
139
264
  const element = await window.weaveDOM.query('h1');
265
+ // Returns: { exists: boolean, value?: string, outerHTML?: string }
140
266
 
141
267
  // Get text content
142
268
  const text = await window.weaveDOM.getText('h1');
143
269
 
144
- // Get attribute
145
- const href = await window.weaveDOM.getAttribute('a', 'href');
146
-
147
- // Check if element has class
148
- const hasClass = await window.weaveDOM.hasClass('.btn', 'active');
270
+ // Get form data
271
+ const formData = await window.weaveDOM.getFormData('form');
272
+ // Returns: { formId, formName, fields: [...] }
149
273
  ```
150
274
 
151
275
  #### Write Operations
@@ -154,70 +278,207 @@ const hasClass = await window.weaveDOM.hasClass('.btn', 'active');
154
278
  // Set text
155
279
  await window.weaveDOM.setText('h1', 'New Title');
156
280
 
157
- // Add class
158
- await window.weaveDOM.addClass('.btn', 'active');
281
+ // Set form field value
282
+ await window.weaveDOM.setFormFieldValue('#email', 'user@example.com', true);
159
283
 
160
- // Set style
161
- await window.weaveDOM.setStyle('h1', 'color', 'red');
284
+ // Click element
285
+ await window.weaveDOM.clickElement('.submit-btn');
162
286
 
163
- // Set attribute
164
- await window.weaveDOM.setAttribute('input', 'placeholder', 'Enter text');
287
+ // Remove element
288
+ await window.weaveDOM.removeElement('.old-element');
165
289
  ```
166
290
 
167
- #### DOM Manipulation
291
+ #### DOM Injection
168
292
 
169
293
  ```typescript
170
- // Insert HTML
171
- await window.weaveDOM.insertHTML('.container', '<p>New content</p>', 'beforeend');
294
+ // Inject HTML element
295
+ const elementId = await window.weaveDOM.injectElement(
296
+ '.target-container',
297
+ 'beforeend',
298
+ '<button id="my-btn">Click Me</button>',
299
+ {
300
+ onClick: async () => {
301
+ console.log('Button clicked!');
302
+ }
303
+ }
304
+ );
172
305
 
173
- // Remove element
174
- await window.weaveDOM.removeElement('.old-element');
306
+ // Remove injected element
307
+ await window.weaveDOM.removeInjectedElement(elementId);
308
+ ```
309
+
310
+ #### Event Listeners
311
+
312
+ ```typescript
313
+ // Start form click listener
314
+ await window.weaveDOM.startFormClickListener(async (data) => {
315
+ console.log('Form detected:', data.formData);
316
+ await window.weaveDOM.stopFormClickListener();
317
+ });
318
+
319
+ // Watch element for changes
320
+ const watcherId = await window.weaveDOM.watchElement(
321
+ '.target',
322
+ (data) => {
323
+ console.log('Element changed:', data.changeType);
324
+ },
325
+ { watchChildren: true, watchAttributes: true }
326
+ );
327
+
328
+ // Stop watching
329
+ await window.weaveDOM.unwatchElement(watcherId);
330
+ ```
331
+
332
+ ### WeaveAPIClient
333
+
334
+ API for accessing backend services. Available as `this.weaveAPI` or `window.weaveAPI`.
335
+
336
+ #### App Data Management
337
+
338
+ ```typescript
339
+ // Create app data
340
+ await this.weaveAPI.appData.create({
341
+ dataKey: 'my-key',
342
+ data: { content: '...', timestamp: new Date() }
343
+ });
344
+
345
+ // Get all app data
346
+ const response = await this.weaveAPI.appData.getAll();
347
+ const allData = response.data || [];
348
+
349
+ // Update existing data
350
+ await this.weaveAPI.appData.update(dataId, {
351
+ dataKey: 'my-key',
352
+ data: { content: '...', timestamp: new Date() }
353
+ });
354
+ ```
355
+
356
+ #### AI Integration
357
+
358
+ ```typescript
359
+ // Call AI for text analysis
360
+ const response = await this.weaveAPI.ai.chat({
361
+ prompt: 'Extract patient name from this text: ...',
362
+ context: 'Medical form filling',
363
+ disableJsonExtraction: false
364
+ });
365
+
366
+ console.log(response.response);
175
367
  ```
176
368
 
369
+ #### Utilities
370
+
371
+ ```typescript
372
+ // Convert HTML to Markdown
373
+ const markdown = window.weaveAPI.utils.htmlToMarkdown(htmlString);
374
+
375
+ // Convert Markdown to HTML
376
+ const html = window.weaveAPI.utils.markdownToHtml(markdownString);
377
+ ```
378
+
379
+ ## Advanced Topics
380
+
381
+ ### Settings & Configuration
382
+
383
+ Settings are injected from the Enterprise Console and displayed as auto-extracted form fields:
384
+
385
+ ```typescript
386
+ interface MyAppSettings {
387
+ /**
388
+ * @description API endpoint for the service
389
+ * @default "https://api.example.com"
390
+ */
391
+ apiEndpoint?: string;
392
+
393
+ /**
394
+ * @description Enable debug logging
395
+ * @default false
396
+ */
397
+ debugMode?: boolean;
398
+ }
399
+
400
+ class MyApp extends WeaveBaseApp<MyAppSettings, MyAppState> {
401
+ constructor() {
402
+ super({ /* ... */ });
403
+
404
+ const endpoint = this.appSettings?.apiEndpoint || 'https://api.example.com';
405
+ const debug = this.appSettings?.debugMode || false;
406
+ }
407
+ }
408
+ ```
409
+
410
+ ### Error Handling
411
+
412
+ ```typescript
413
+ try {
414
+ const data = await this.weaveAPI.appData.getAll();
415
+ } catch (error) {
416
+ console.error('Failed to fetch data:', error);
417
+ this.setState({ error: error.message });
418
+ this.render();
419
+ }
420
+ ```
421
+
422
+ ### Performance Tips
423
+
424
+ - Use `async/await` for API calls to avoid blocking UI
425
+ - Debounce rapid state changes with timers
426
+ - Clear intervals and listeners in `cleanup()`
427
+ - Use `isCheckingContainer` flags to prevent overlapping async callbacks
428
+ - Minimize re-renders by updating state only when needed
429
+
177
430
  ## Build Process
178
431
 
179
- The build uses two commands:
432
+ The build pipeline has two steps:
433
+
434
+ 1. **TypeScript Compilation** (`tsc`)
435
+ - Compiles TypeScript to ES2020 JavaScript
436
+ - Outputs to `dist/`
180
437
 
181
- 1. **`tsc`** - TypeScript compiler (ES2020 target)
182
- 2. **`weave-build`** - SDK's build tool that:
183
- - Removes import statements (SDK is global)
184
- - Replaces SDK references with `window.*`
185
- - Adds header comment
186
- - Generates clean, readable JavaScript
438
+ 2. **SDK Build** (`weave-compile`)
439
+ - Removes SDK imports (SDK is global)
440
+ - Replaces SDK references with `window.*`
441
+ - Generates final output ready for deployment
187
442
 
188
- You can also run `weave-build` manually after compiling:
443
+ You can also run manually:
189
444
  ```bash
190
445
  tsc
191
- weave-build
446
+ weave-compile
192
447
  ```
193
448
 
194
449
  ## Security
195
450
 
196
451
  - ✅ **Selector Validation** - Prevents dangerous selectors
197
- - ✅ **HTML Sanitization** - Removes scripts and event handlers
452
+ - ✅ **HTML Sanitization** - Removes scripts and dangerous content
198
453
  - ✅ **Attribute Whitelist** - Blocks dangerous attributes
199
454
  - ✅ **Shadow DOM Isolation** - Scoped styles and encapsulation
200
- - ✅ **No Direct DOM Access** - All operations go through secure bridge
455
+ - ✅ **Secure Bridge** - All DOM operations go through security validation
201
456
 
202
457
  ## Project Structure
203
458
 
204
459
  ```
205
460
  my-app/
206
461
  ├── src/
207
- │ └── app.ts # Your TypeScript source
462
+ │ └── app.ts # Your TypeScript app
208
463
  ├── dist/
209
- │ └── app.js # Compiled JavaScript (upload this)
464
+ │ └── my-app.js # Compiled output (upload this)
210
465
  ├── package.json
211
466
  ├── tsconfig.json
467
+ ├── SIDEKICK_SPEC.md # AI assistant guide
212
468
  └── README.md
213
469
  ```
214
470
 
215
- **Note:** The build script (`weave-build`) is part of the SDK, not copied to your app.
471
+ ## Troubleshooting
472
+
473
+ ### "TypeScript not found in SDK"
474
+ Make sure to run `npm install` in your app directory after initialization.
216
475
 
217
- ## Examples
476
+ ### Form not filling
477
+ Check that selectors match the actual form structure. Use browser DevTools to inspect the form.
218
478
 
219
- See the [examples directory](./examples) for complete app examples.
479
+ ### Button not injecting
480
+ Verify the target selector exists before injection attempt. Check browser console for errors.
220
481
 
221
- ## License
482
+ ### State not persisting
483
+ Use `this.weaveAPI.appData.*` methods to persist data to backend. In-memory state is lost on refresh.
222
484
 
223
- MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weave-apps/sdk",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "SDK for building Weave Micro Apps",
5
5
  "publishConfig": {
6
6
  "access": "public"