experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 363 lines 8.2 kB view raw view rendered
1# Peek Core API Reference 2 3The `window.app` API is automatically injected into all `peek://` pages. This API provides access to window management, data storage, messaging, and shortcuts. 4 5## Context Detection 6 7```javascript 8// Check if running in peek:// context 9if (window.app) { 10 // API available 11} 12 13// Source address of current page 14const source = window.location.toString(); 15 16// Context types: 17// - peek://app/... Core application pages 18// - peek://ext/{id}/... Extension pages 19``` 20 21## Window Management 22 23### `window.app.window.open(url, options)` 24 25Open a new window. 26 27```javascript 28const result = await window.app.window.open('peek://app/settings/settings.html', { 29 key: 'settings', // Reuse window with same key 30 width: 900, // Window width 31 height: 650, // Window height 32 x: 100, // X position 33 y: 100, // Y position 34 title: 'Settings', // Window title 35 modal: true, // Modal behavior 36 transparent: false, // Transparent background 37 decorations: true, // Window decorations 38 alwaysOnTop: false, // Stay on top 39 visible: true, // Initially visible 40 resizable: true, // Allow resize 41 keepLive: false // Keep window alive when closed 42}); 43// Returns: { success: true, id: 'window_label' } 44``` 45 46### `window.app.window.close(id?)` 47 48Close a window. If no id, closes current window. 49 50```javascript 51await window.app.window.close(); // Close current 52await window.app.window.close('settings'); // Close by id 53await window.app.window.close({ id: 'settings' }); // Object form 54``` 55 56### `window.app.window.hide(id?)` / `window.app.window.show(id?)` 57 58Toggle window visibility. 59 60```javascript 61await window.app.window.hide('main'); 62await window.app.window.show('main'); 63``` 64 65### `window.app.window.focus(id?)` 66 67Bring window to front and focus it. 68 69```javascript 70await window.app.window.focus('settings'); 71``` 72 73### `window.app.window.list()` 74 75List all open windows. 76 77```javascript 78const result = await window.app.window.list(); 79// Returns: { 80// success: true, 81// data: [{ 82// id: 'main', 83// label: 'main', 84// url: 'peek://app/background.html', 85// source: 'peek://app/background.html', 86// visible: false, 87// focused: false 88// }, ...] 89// } 90``` 91 92### `window.app.window.exists(id)` 93 94Check if a window exists. 95 96```javascript 97const result = await window.app.window.exists('settings'); 98// Returns: { success: true, data: true } 99``` 100 101## Datastore 102 103All datastore methods return `{ success: boolean, data?: any, error?: string }`. 104 105### Addresses 106 107```javascript 108// Add a new address 109const result = await window.app.datastore.addAddress('https://example.com', { 110 title: 'Example', 111 favicon: 'https://example.com/favicon.ico' 112}); 113// Returns: { success: true, data: { id: 'addr_123', ... } } 114 115// Get address by ID 116const addr = await window.app.datastore.getAddress('addr_123'); 117 118// Update address 119await window.app.datastore.updateAddress('addr_123', { 120 title: 'New Title' 121}); 122 123// Query addresses 124const results = await window.app.datastore.queryAddresses({ 125 uri: 'example.com', // Partial match 126 limit: 10, 127 offset: 0 128}); 129``` 130 131### Visits 132 133```javascript 134// Add a visit 135await window.app.datastore.addVisit('addr_123', { 136 referrer: 'addr_456' 137}); 138 139// Query visits 140const visits = await window.app.datastore.queryVisits({ 141 addressId: 'addr_123', 142 limit: 50 143}); 144``` 145 146### Tags 147 148```javascript 149// Get or create a tag 150const tag = await window.app.datastore.getOrCreateTag('important'); 151// Returns: { success: true, data: { id: 'tag_123', name: 'important' } } 152 153// Tag an address 154await window.app.datastore.tagAddress('addr_123', 'tag_123'); 155 156// Untag an address 157await window.app.datastore.untagAddress('addr_123', 'tag_123'); 158 159// Get tags for an address 160const tags = await window.app.datastore.getAddressTags('addr_123'); 161``` 162 163### Generic Table Access 164 165```javascript 166// Get all rows from a table 167const table = await window.app.datastore.getTable('extensions'); 168// Returns: { success: true, data: { row_id: { ... }, ... } } 169 170// Set a row 171await window.app.datastore.setRow('extensions', 'my-ext', { 172 name: 'My Extension', 173 enabled: true 174}); 175``` 176 177### Statistics 178 179```javascript 180const stats = await window.app.datastore.getStats(); 181// Returns: { success: true, data: { 182// addresses: 150, 183// visits: 1200, 184// tags: 25 185// }} 186``` 187 188## PubSub Messaging 189 190Cross-window communication via publish/subscribe. 191 192### Scopes 193 194```javascript 195window.app.scopes = { 196 SYSTEM: 1, // System messages 197 SELF: 2, // Same source only 198 GLOBAL: 3 // All windows 199}; 200``` 201 202### `window.app.publish(topic, message, scope)` 203 204Publish a message. 205 206```javascript 207window.app.publish('settings:changed', { theme: 'dark' }, window.app.scopes.GLOBAL); 208``` 209 210### `window.app.subscribe(topic, callback, scope)` 211 212Subscribe to messages. 213 214```javascript 215window.app.subscribe('settings:changed', (msg) => { 216 console.log('Settings changed:', msg.data); 217}, window.app.scopes.GLOBAL); 218``` 219 220## Keyboard Shortcuts 221 222### `window.app.shortcuts.register(shortcut, callback, options)` 223 224Register a keyboard shortcut. 225 226```javascript 227// Local shortcut (only when app focused) 228window.app.shortcuts.register('Command+K', () => { 229 console.log('Command+K pressed'); 230}); 231 232// Global shortcut (works even when app not focused) 233window.app.shortcuts.register('Option+Space', () => { 234 console.log('Global shortcut triggered'); 235}, { global: true }); 236``` 237 238**Shortcut format:** 239- Modifiers: `Command`, `Control`, `Alt`, `Option`, `Shift`, `CommandOrControl` 240- Keys: `A-Z`, `0-9`, `F1-F12`, `Space`, `Enter`, `Escape`, `ArrowUp`, etc. 241- Examples: `Command+Shift+P`, `Alt+1`, `Option+ArrowDown` 242 243### `window.app.shortcuts.unregister(shortcut, options)` 244 245Unregister a shortcut. 246 247```javascript 248window.app.shortcuts.unregister('Command+K'); 249window.app.shortcuts.unregister('Option+Space', { global: true }); 250``` 251 252## Commands (Command Palette) 253 254Register commands that appear in the command palette. 255 256### `window.app.commands.register(command)` 257 258```javascript 259window.app.commands.register({ 260 name: 'my-extension:do-thing', 261 description: 'Do the thing', 262 execute: () => { 263 console.log('Doing the thing'); 264 } 265}); 266``` 267 268### `window.app.commands.unregister(name)` 269 270```javascript 271window.app.commands.unregister('my-extension:do-thing'); 272``` 273 274### `window.app.commands.getAll()` 275 276```javascript 277const commands = await window.app.commands.getAll(); 278``` 279 280## Escape Handling 281 282Handle the ESC key to prevent window from closing. 283 284```javascript 285window.app.escape.onEscape(() => { 286 if (hasUnsavedChanges) { 287 showConfirmDialog(); 288 return { handled: true }; // Prevent close 289 } 290 return { handled: false }; // Allow close 291}); 292``` 293 294## Logging 295 296Log messages to the backend console. 297 298```javascript 299window.app.log('Something happened', { detail: 'value' }); 300// Output in terminal: [peek://app/mypage.html] Something happened { detail: 'value' } 301``` 302 303## Debug Mode 304 305```javascript 306if (window.app.debug) { 307 console.log('Debug mode enabled'); 308} 309 310// Debug levels 311window.app.debugLevels = { BASIC: 1, FIRST_RUN: 2 }; 312window.app.debugLevel; // Current level 313``` 314 315## Extensions API 316 317Only available in core app pages (`peek://app/...`). 318 319```javascript 320// Check permission 321if (window.app.extensions._hasPermission()) { 322 const exts = await window.app.extensions.list(); 323} 324``` 325 326## Settings API 327 328Only available in extension pages (`peek://ext/{id}/...`). 329 330```javascript 331// Get all settings 332const settings = await window.app.settings.get(); 333 334// Set all settings 335await window.app.settings.set({ theme: 'dark' }); 336 337// Get/set individual keys 338const theme = await window.app.settings.getKey('theme'); 339await window.app.settings.setKey('theme', 'light'); 340``` 341 342## Response Format 343 344All async API methods return a consistent response format: 345 346```javascript 347{ 348 success: true, // Operation succeeded 349 data: any, // Result data (if applicable) 350 error: string // Error message (if success: false) 351} 352``` 353 354Always check `success` before using `data`: 355 356```javascript 357const result = await window.app.datastore.getAddress(id); 358if (result.success) { 359 console.log(result.data); 360} else { 361 console.error(result.error); 362} 363```