@auroraview/sdk 0.3.25 → 0.3.27
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/index.cjs +266 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -1
- package/dist/index.d.ts +101 -1
- package/dist/index.js +266 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -219,9 +219,275 @@ function getAuroraView() {
|
|
|
219
219
|
return createAuroraView();
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
// src/inject/plugins/utils.ts
|
|
223
|
+
async function invokePlugin(plugin, command, args) {
|
|
224
|
+
if (!window.auroraview || !window.auroraview.invoke) {
|
|
225
|
+
throw new Error("AuroraView bridge not available");
|
|
226
|
+
}
|
|
227
|
+
const result = await window.auroraview.invoke(
|
|
228
|
+
`plugin:${plugin}|${command}`,
|
|
229
|
+
args || {}
|
|
230
|
+
);
|
|
231
|
+
if (result && result.success === false) {
|
|
232
|
+
const error = new Error(result.error || "Unknown error");
|
|
233
|
+
error.code = result.code || "UNKNOWN";
|
|
234
|
+
throw error;
|
|
235
|
+
}
|
|
236
|
+
return result;
|
|
237
|
+
}
|
|
238
|
+
function attachPlugin(name, api) {
|
|
239
|
+
if (window.auroraview) {
|
|
240
|
+
window.auroraview[name] = api;
|
|
241
|
+
console.log(`[AuroraView] ${name.charAt(0).toUpperCase() + name.slice(1)} plugin initialized`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function initPlugin(name, api) {
|
|
245
|
+
if (window.auroraview) {
|
|
246
|
+
attachPlugin(name, api);
|
|
247
|
+
} else {
|
|
248
|
+
const observer2 = setInterval(function() {
|
|
249
|
+
if (window.auroraview) {
|
|
250
|
+
clearInterval(observer2);
|
|
251
|
+
attachPlugin(name, api);
|
|
252
|
+
}
|
|
253
|
+
}, 10);
|
|
254
|
+
setTimeout(function() {
|
|
255
|
+
clearInterval(observer2);
|
|
256
|
+
}, 5e3);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// src/inject/plugins/interactive.ts
|
|
261
|
+
var DEFAULT_CONFIG = {
|
|
262
|
+
attribute: "data-interactive",
|
|
263
|
+
debounceMs: 100,
|
|
264
|
+
observeChanges: true,
|
|
265
|
+
observeResize: true,
|
|
266
|
+
observeScroll: true
|
|
267
|
+
};
|
|
268
|
+
var config = { ...DEFAULT_CONFIG };
|
|
269
|
+
var enabled = true;
|
|
270
|
+
var observer = null;
|
|
271
|
+
var resizeObserver = null;
|
|
272
|
+
var debounceTimer = null;
|
|
273
|
+
var lastRegions = [];
|
|
274
|
+
function collectRegions() {
|
|
275
|
+
const elements = document.querySelectorAll(`[${config.attribute}]`);
|
|
276
|
+
const regions = [];
|
|
277
|
+
elements.forEach((element) => {
|
|
278
|
+
const rect = element.getBoundingClientRect();
|
|
279
|
+
if (rect.width === 0 || rect.height === 0) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (rect.bottom < 0 || rect.top > window.innerHeight || rect.right < 0 || rect.left > window.innerWidth) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
regions.push({
|
|
286
|
+
x: Math.round(rect.left),
|
|
287
|
+
y: Math.round(rect.top),
|
|
288
|
+
width: Math.round(rect.width),
|
|
289
|
+
height: Math.round(rect.height),
|
|
290
|
+
id: element.id || void 0
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
return regions;
|
|
294
|
+
}
|
|
295
|
+
function regionsChanged(newRegions) {
|
|
296
|
+
if (newRegions.length !== lastRegions.length) {
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
for (let i = 0; i < newRegions.length; i++) {
|
|
300
|
+
const a = newRegions[i];
|
|
301
|
+
const b = lastRegions[i];
|
|
302
|
+
if (a.x !== b.x || a.y !== b.y || a.width !== b.width || a.height !== b.height) {
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
async function sendRegions(regions) {
|
|
309
|
+
try {
|
|
310
|
+
await invokePlugin("window", "update_interactive_regions", { regions });
|
|
311
|
+
console.debug("[AuroraView] Updated interactive regions:", regions.length);
|
|
312
|
+
} catch (error) {
|
|
313
|
+
console.error("[AuroraView] Failed to update interactive regions:", error);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function scheduleUpdate() {
|
|
317
|
+
if (!enabled) return;
|
|
318
|
+
if (debounceTimer) {
|
|
319
|
+
clearTimeout(debounceTimer);
|
|
320
|
+
}
|
|
321
|
+
debounceTimer = setTimeout(() => {
|
|
322
|
+
const regions = collectRegions();
|
|
323
|
+
if (regionsChanged(regions)) {
|
|
324
|
+
lastRegions = regions;
|
|
325
|
+
sendRegions(regions);
|
|
326
|
+
}
|
|
327
|
+
}, config.debounceMs);
|
|
328
|
+
}
|
|
329
|
+
function startObserving() {
|
|
330
|
+
if (!config.observeChanges) return;
|
|
331
|
+
observer = new MutationObserver((mutations) => {
|
|
332
|
+
let needsUpdate = false;
|
|
333
|
+
for (const mutation of mutations) {
|
|
334
|
+
if (mutation.type === "childList") {
|
|
335
|
+
for (const node of mutation.addedNodes) {
|
|
336
|
+
if (node instanceof Element && node.hasAttribute(config.attribute)) {
|
|
337
|
+
needsUpdate = true;
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
for (const node of mutation.removedNodes) {
|
|
342
|
+
if (node instanceof Element && node.hasAttribute(config.attribute)) {
|
|
343
|
+
needsUpdate = true;
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
} else if (mutation.type === "attributes") {
|
|
348
|
+
if (mutation.attributeName === config.attribute) {
|
|
349
|
+
needsUpdate = true;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (needsUpdate) break;
|
|
353
|
+
}
|
|
354
|
+
if (needsUpdate) {
|
|
355
|
+
scheduleUpdate();
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
observer.observe(document.body, {
|
|
359
|
+
childList: true,
|
|
360
|
+
subtree: true,
|
|
361
|
+
attributes: true,
|
|
362
|
+
attributeFilter: [config.attribute]
|
|
363
|
+
});
|
|
364
|
+
if (config.observeResize) {
|
|
365
|
+
resizeObserver = new ResizeObserver(() => {
|
|
366
|
+
scheduleUpdate();
|
|
367
|
+
});
|
|
368
|
+
document.querySelectorAll(`[${config.attribute}]`).forEach((element) => {
|
|
369
|
+
resizeObserver?.observe(element);
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
if (config.observeResize) {
|
|
373
|
+
window.addEventListener("resize", scheduleUpdate, { passive: true });
|
|
374
|
+
}
|
|
375
|
+
if (config.observeScroll) {
|
|
376
|
+
window.addEventListener("scroll", scheduleUpdate, { passive: true });
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
function stopObserving() {
|
|
380
|
+
if (observer) {
|
|
381
|
+
observer.disconnect();
|
|
382
|
+
observer = null;
|
|
383
|
+
}
|
|
384
|
+
if (resizeObserver) {
|
|
385
|
+
resizeObserver.disconnect();
|
|
386
|
+
resizeObserver = null;
|
|
387
|
+
}
|
|
388
|
+
window.removeEventListener("resize", scheduleUpdate);
|
|
389
|
+
window.removeEventListener("scroll", scheduleUpdate);
|
|
390
|
+
if (debounceTimer) {
|
|
391
|
+
clearTimeout(debounceTimer);
|
|
392
|
+
debounceTimer = null;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
var interactive = {
|
|
396
|
+
/**
|
|
397
|
+
* Manually trigger a region update
|
|
398
|
+
*/
|
|
399
|
+
update() {
|
|
400
|
+
scheduleUpdate();
|
|
401
|
+
},
|
|
402
|
+
/**
|
|
403
|
+
* Force immediate update (bypasses debounce)
|
|
404
|
+
*/
|
|
405
|
+
forceUpdate() {
|
|
406
|
+
if (debounceTimer) {
|
|
407
|
+
clearTimeout(debounceTimer);
|
|
408
|
+
debounceTimer = null;
|
|
409
|
+
}
|
|
410
|
+
const regions = collectRegions();
|
|
411
|
+
lastRegions = regions;
|
|
412
|
+
sendRegions(regions);
|
|
413
|
+
},
|
|
414
|
+
/**
|
|
415
|
+
* Get current interactive regions
|
|
416
|
+
*/
|
|
417
|
+
getRegions() {
|
|
418
|
+
return collectRegions();
|
|
419
|
+
},
|
|
420
|
+
/**
|
|
421
|
+
* Enable or disable tracking
|
|
422
|
+
*/
|
|
423
|
+
setEnabled(value) {
|
|
424
|
+
enabled = value;
|
|
425
|
+
if (enabled) {
|
|
426
|
+
startObserving();
|
|
427
|
+
scheduleUpdate();
|
|
428
|
+
} else {
|
|
429
|
+
stopObserving();
|
|
430
|
+
lastRegions = [];
|
|
431
|
+
sendRegions([]);
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
/**
|
|
435
|
+
* Check if tracking is enabled
|
|
436
|
+
*/
|
|
437
|
+
isEnabled() {
|
|
438
|
+
return enabled;
|
|
439
|
+
},
|
|
440
|
+
/**
|
|
441
|
+
* Update configuration
|
|
442
|
+
*/
|
|
443
|
+
configure(newConfig) {
|
|
444
|
+
const wasObserving = observer !== null;
|
|
445
|
+
if (wasObserving) {
|
|
446
|
+
stopObserving();
|
|
447
|
+
}
|
|
448
|
+
config = { ...config, ...newConfig };
|
|
449
|
+
if (wasObserving && enabled) {
|
|
450
|
+
startObserving();
|
|
451
|
+
scheduleUpdate();
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
/**
|
|
455
|
+
* Get current configuration
|
|
456
|
+
*/
|
|
457
|
+
getConfig() {
|
|
458
|
+
return { ...config };
|
|
459
|
+
},
|
|
460
|
+
/**
|
|
461
|
+
* Initialize the plugin (called automatically)
|
|
462
|
+
*/
|
|
463
|
+
init() {
|
|
464
|
+
if (document.readyState === "loading") {
|
|
465
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
466
|
+
startObserving();
|
|
467
|
+
scheduleUpdate();
|
|
468
|
+
});
|
|
469
|
+
} else {
|
|
470
|
+
startObserving();
|
|
471
|
+
scheduleUpdate();
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
/**
|
|
475
|
+
* Cleanup the plugin
|
|
476
|
+
*/
|
|
477
|
+
destroy() {
|
|
478
|
+
stopObserving();
|
|
479
|
+
lastRegions = [];
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
initPlugin("interactive", interactive);
|
|
483
|
+
if (typeof document !== "undefined") {
|
|
484
|
+
interactive.init();
|
|
485
|
+
}
|
|
486
|
+
|
|
222
487
|
exports.EventEmitter = EventEmitter;
|
|
223
488
|
exports.createAuroraView = createAuroraView;
|
|
224
489
|
exports.getAuroraView = getAuroraView;
|
|
225
490
|
exports.getGlobalEmitter = getGlobalEmitter;
|
|
491
|
+
exports.interactive = interactive;
|
|
226
492
|
//# sourceMappingURL=index.cjs.map
|
|
227
493
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/events.ts","../src/core/bridge.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * AuroraView SDK Event System\n *\n * Provides a type-safe event emitter with proper unsubscribe support.\n */\n\nimport type { EventHandler, Unsubscribe } from './types';\n\n/**\n * Event emitter with unsubscribe support\n */\nexport class EventEmitter {\n private handlers = new Map<string, Set<EventHandler>>();\n\n /**\n * Subscribe to an event\n * @param event - Event name\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n const handlers = this.handlers.get(event)!;\n handlers.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => {\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n this.handlers.delete(event);\n }\n };\n }\n\n /**\n * Subscribe to an event once\n * @param event - Event name\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n const wrapper: EventHandler<T> = (data) => {\n unsubscribe();\n handler(data);\n };\n const unsubscribe = this.on(event, wrapper);\n return unsubscribe;\n }\n\n /**\n * Emit an event to all handlers\n * @param event - Event name\n * @param data - Event data\n */\n emit<T = unknown>(event: string, data: T): void {\n const handlers = this.handlers.get(event);\n if (!handlers) return;\n\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (e) {\n console.error(`[AuroraView] Error in event handler for \"${event}\":`, e);\n }\n });\n }\n\n /**\n * Remove event handler(s)\n * @param event - Event name\n * @param handler - Optional specific handler to remove\n */\n off(event: string, handler?: EventHandler): void {\n if (handler) {\n this.handlers.get(event)?.delete(handler);\n } else {\n this.handlers.delete(event);\n }\n }\n\n /**\n * Check if event has handlers\n * @param event - Event name\n */\n hasHandlers(event: string): boolean {\n const handlers = this.handlers.get(event);\n return handlers !== undefined && handlers.size > 0;\n }\n\n /**\n * Get handler count for an event\n * @param event - Event name\n */\n handlerCount(event: string): number {\n return this.handlers.get(event)?.size ?? 0;\n }\n\n /**\n * Remove all handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n/** Singleton event emitter instance */\nlet globalEmitter: EventEmitter | null = null;\n\n/**\n * Get the global event emitter instance\n */\nexport function getGlobalEmitter(): EventEmitter {\n if (!globalEmitter) {\n globalEmitter = new EventEmitter();\n }\n return globalEmitter;\n}\n","/**\n * AuroraView SDK Bridge Client\n *\n * Provides a type-safe wrapper around the native bridge API.\n */\n\nimport { EventEmitter, getGlobalEmitter } from './events';\nimport type {\n EventHandler,\n Unsubscribe,\n AuroraViewBridge,\n FileSystemAPI,\n DialogAPI,\n ClipboardAPI,\n ShellAPI,\n AuroraViewState,\n} from './types';\n\n/**\n * AuroraView client interface\n */\nexport interface AuroraViewClient {\n /** Call a Python method (RPC-style) */\n call<T = unknown>(method: string, params?: unknown): Promise<T>;\n\n /** Invoke a plugin command */\n invoke<T = unknown>(cmd: string, args?: Record<string, unknown>): Promise<T>;\n\n /** Send an event to Python (fire-and-forget) */\n emit(event: string, data?: unknown): void;\n\n /** Subscribe to an event from Python */\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe;\n\n /** Subscribe to an event once */\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe;\n\n /** Unsubscribe from an event */\n off(event: string, handler?: EventHandler): void;\n\n /** Check if bridge is ready */\n isReady(): boolean;\n\n /** Wait for bridge to be ready */\n whenReady(): Promise<AuroraViewClient>;\n\n /** Get the raw bridge object */\n getRawBridge(): AuroraViewBridge | undefined;\n\n /** File system API */\n readonly fs: FileSystemAPI | undefined;\n\n /** Dialog API */\n readonly dialog: DialogAPI | undefined;\n\n /** Clipboard API */\n readonly clipboard: ClipboardAPI | undefined;\n\n /** Shell API */\n readonly shell: ShellAPI | undefined;\n\n /** Shared state */\n readonly state: AuroraViewState | undefined;\n}\n\n/**\n * Internal client implementation\n */\nclass AuroraViewClientImpl implements AuroraViewClient {\n private events: EventEmitter;\n private interceptInstalled = false;\n\n constructor() {\n this.events = getGlobalEmitter();\n this.installTriggerIntercept();\n }\n\n /**\n * Install intercept on window.auroraview.trigger to forward events\n */\n private installTriggerIntercept(): void {\n if (this.interceptInstalled) return;\n if (typeof window === 'undefined') return;\n\n const install = () => {\n const bridge = window.auroraview;\n if (!bridge) return;\n\n const originalTrigger = bridge.trigger;\n bridge.trigger = (event: string, detail?: unknown) => {\n // Call original trigger first\n originalTrigger?.call(bridge, event, detail);\n // Forward to our event system\n this.events.emit(event, detail);\n };\n\n this.interceptInstalled = true;\n };\n\n // Try to install immediately\n if (window.auroraview) {\n install();\n } else {\n // Wait for bridge to be available\n const checkInterval = setInterval(() => {\n if (window.auroraview) {\n clearInterval(checkInterval);\n install();\n }\n }, 10);\n\n // Stop checking after 10 seconds\n setTimeout(() => clearInterval(checkInterval), 10000);\n }\n }\n\n call<T = unknown>(method: string, params?: unknown): Promise<T> {\n const bridge = window.auroraview;\n if (!bridge) {\n return Promise.reject(new Error('AuroraView bridge not available'));\n }\n return bridge.call<T>(method, params);\n }\n\n invoke<T = unknown>(cmd: string, args?: Record<string, unknown>): Promise<T> {\n const bridge = window.auroraview;\n if (!bridge) {\n return Promise.reject(new Error('AuroraView bridge not available'));\n }\n return bridge.invoke<T>(cmd, args);\n }\n\n emit(event: string, data?: unknown): void {\n const bridge = window.auroraview;\n if (bridge) {\n bridge.send_event(event, data);\n }\n }\n\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n return this.events.on(event, handler);\n }\n\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n return this.events.once(event, handler);\n }\n\n off(event: string, handler?: EventHandler): void {\n this.events.off(event, handler);\n }\n\n isReady(): boolean {\n return window.auroraview?._ready === true;\n }\n\n whenReady(): Promise<AuroraViewClient> {\n return new Promise((resolve) => {\n if (this.isReady()) {\n resolve(this);\n } else if (window.auroraview) {\n window.auroraview.whenReady().then(() => {\n this.installTriggerIntercept();\n resolve(this);\n });\n } else {\n // Wait for bridge to appear\n const checkInterval = setInterval(() => {\n if (window.auroraview) {\n clearInterval(checkInterval);\n window.auroraview.whenReady().then(() => {\n this.installTriggerIntercept();\n resolve(this);\n });\n }\n }, 10);\n\n // Timeout after 30 seconds\n setTimeout(() => {\n clearInterval(checkInterval);\n resolve(this);\n }, 30000);\n }\n });\n }\n\n getRawBridge(): AuroraViewBridge | undefined {\n return window.auroraview;\n }\n\n get fs(): FileSystemAPI | undefined {\n return window.auroraview?.fs;\n }\n\n get dialog(): DialogAPI | undefined {\n return window.auroraview?.dialog;\n }\n\n get clipboard(): ClipboardAPI | undefined {\n return window.auroraview?.clipboard;\n }\n\n get shell(): ShellAPI | undefined {\n return window.auroraview?.shell;\n }\n\n get state(): AuroraViewState | undefined {\n return window.auroraview?.state;\n }\n}\n\n/** Singleton client instance */\nlet clientInstance: AuroraViewClient | null = null;\n\n/**\n * Create or get the AuroraView client instance\n */\nexport function createAuroraView(): AuroraViewClient {\n if (!clientInstance) {\n clientInstance = new AuroraViewClientImpl();\n }\n return clientInstance;\n}\n\n/**\n * Get the AuroraView client instance (alias for createAuroraView)\n */\nexport function getAuroraView(): AuroraViewClient {\n return createAuroraView();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/events.ts","../src/core/bridge.ts","../src/inject/plugins/utils.ts","../src/inject/plugins/interactive.ts"],"names":["observer"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * AuroraView SDK Event System\n *\n * Provides a type-safe event emitter with proper unsubscribe support.\n */\n\nimport type { EventHandler, Unsubscribe } from './types';\n\n/**\n * Event emitter with unsubscribe support\n */\nexport class EventEmitter {\n private handlers = new Map<string, Set<EventHandler>>();\n\n /**\n * Subscribe to an event\n * @param event - Event name\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n const handlers = this.handlers.get(event)!;\n handlers.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => {\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n this.handlers.delete(event);\n }\n };\n }\n\n /**\n * Subscribe to an event once\n * @param event - Event name\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n const wrapper: EventHandler<T> = (data) => {\n unsubscribe();\n handler(data);\n };\n const unsubscribe = this.on(event, wrapper);\n return unsubscribe;\n }\n\n /**\n * Emit an event to all handlers\n * @param event - Event name\n * @param data - Event data\n */\n emit<T = unknown>(event: string, data: T): void {\n const handlers = this.handlers.get(event);\n if (!handlers) return;\n\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (e) {\n console.error(`[AuroraView] Error in event handler for \"${event}\":`, e);\n }\n });\n }\n\n /**\n * Remove event handler(s)\n * @param event - Event name\n * @param handler - Optional specific handler to remove\n */\n off(event: string, handler?: EventHandler): void {\n if (handler) {\n this.handlers.get(event)?.delete(handler);\n } else {\n this.handlers.delete(event);\n }\n }\n\n /**\n * Check if event has handlers\n * @param event - Event name\n */\n hasHandlers(event: string): boolean {\n const handlers = this.handlers.get(event);\n return handlers !== undefined && handlers.size > 0;\n }\n\n /**\n * Get handler count for an event\n * @param event - Event name\n */\n handlerCount(event: string): number {\n return this.handlers.get(event)?.size ?? 0;\n }\n\n /**\n * Remove all handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n/** Singleton event emitter instance */\nlet globalEmitter: EventEmitter | null = null;\n\n/**\n * Get the global event emitter instance\n */\nexport function getGlobalEmitter(): EventEmitter {\n if (!globalEmitter) {\n globalEmitter = new EventEmitter();\n }\n return globalEmitter;\n}\n","/**\n * AuroraView SDK Bridge Client\n *\n * Provides a type-safe wrapper around the native bridge API.\n */\n\nimport { EventEmitter, getGlobalEmitter } from './events';\nimport type {\n EventHandler,\n Unsubscribe,\n AuroraViewBridge,\n FileSystemAPI,\n DialogAPI,\n ClipboardAPI,\n ShellAPI,\n AuroraViewState,\n} from './types';\n\n/**\n * AuroraView client interface\n */\nexport interface AuroraViewClient {\n /** Call a Python method (RPC-style) */\n call<T = unknown>(method: string, params?: unknown): Promise<T>;\n\n /** Invoke a plugin command */\n invoke<T = unknown>(cmd: string, args?: Record<string, unknown>): Promise<T>;\n\n /** Send an event to Python (fire-and-forget) */\n emit(event: string, data?: unknown): void;\n\n /** Subscribe to an event from Python */\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe;\n\n /** Subscribe to an event once */\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe;\n\n /** Unsubscribe from an event */\n off(event: string, handler?: EventHandler): void;\n\n /** Check if bridge is ready */\n isReady(): boolean;\n\n /** Wait for bridge to be ready */\n whenReady(): Promise<AuroraViewClient>;\n\n /** Get the raw bridge object */\n getRawBridge(): AuroraViewBridge | undefined;\n\n /** File system API */\n readonly fs: FileSystemAPI | undefined;\n\n /** Dialog API */\n readonly dialog: DialogAPI | undefined;\n\n /** Clipboard API */\n readonly clipboard: ClipboardAPI | undefined;\n\n /** Shell API */\n readonly shell: ShellAPI | undefined;\n\n /** Shared state */\n readonly state: AuroraViewState | undefined;\n}\n\n/**\n * Internal client implementation\n */\nclass AuroraViewClientImpl implements AuroraViewClient {\n private events: EventEmitter;\n private interceptInstalled = false;\n\n constructor() {\n this.events = getGlobalEmitter();\n this.installTriggerIntercept();\n }\n\n /**\n * Install intercept on window.auroraview.trigger to forward events\n */\n private installTriggerIntercept(): void {\n if (this.interceptInstalled) return;\n if (typeof window === 'undefined') return;\n\n const install = () => {\n const bridge = window.auroraview;\n if (!bridge) return;\n\n const originalTrigger = bridge.trigger;\n bridge.trigger = (event: string, detail?: unknown) => {\n // Call original trigger first\n originalTrigger?.call(bridge, event, detail);\n // Forward to our event system\n this.events.emit(event, detail);\n };\n\n this.interceptInstalled = true;\n };\n\n // Try to install immediately\n if (window.auroraview) {\n install();\n } else {\n // Wait for bridge to be available\n const checkInterval = setInterval(() => {\n if (window.auroraview) {\n clearInterval(checkInterval);\n install();\n }\n }, 10);\n\n // Stop checking after 10 seconds\n setTimeout(() => clearInterval(checkInterval), 10000);\n }\n }\n\n call<T = unknown>(method: string, params?: unknown): Promise<T> {\n const bridge = window.auroraview;\n if (!bridge) {\n return Promise.reject(new Error('AuroraView bridge not available'));\n }\n return bridge.call<T>(method, params);\n }\n\n invoke<T = unknown>(cmd: string, args?: Record<string, unknown>): Promise<T> {\n const bridge = window.auroraview;\n if (!bridge) {\n return Promise.reject(new Error('AuroraView bridge not available'));\n }\n return bridge.invoke<T>(cmd, args);\n }\n\n emit(event: string, data?: unknown): void {\n const bridge = window.auroraview;\n if (bridge) {\n bridge.send_event(event, data);\n }\n }\n\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n return this.events.on(event, handler);\n }\n\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n return this.events.once(event, handler);\n }\n\n off(event: string, handler?: EventHandler): void {\n this.events.off(event, handler);\n }\n\n isReady(): boolean {\n return window.auroraview?._ready === true;\n }\n\n whenReady(): Promise<AuroraViewClient> {\n return new Promise((resolve) => {\n if (this.isReady()) {\n resolve(this);\n } else if (window.auroraview) {\n window.auroraview.whenReady().then(() => {\n this.installTriggerIntercept();\n resolve(this);\n });\n } else {\n // Wait for bridge to appear\n const checkInterval = setInterval(() => {\n if (window.auroraview) {\n clearInterval(checkInterval);\n window.auroraview.whenReady().then(() => {\n this.installTriggerIntercept();\n resolve(this);\n });\n }\n }, 10);\n\n // Timeout after 30 seconds\n setTimeout(() => {\n clearInterval(checkInterval);\n resolve(this);\n }, 30000);\n }\n });\n }\n\n getRawBridge(): AuroraViewBridge | undefined {\n return window.auroraview;\n }\n\n get fs(): FileSystemAPI | undefined {\n return window.auroraview?.fs;\n }\n\n get dialog(): DialogAPI | undefined {\n return window.auroraview?.dialog;\n }\n\n get clipboard(): ClipboardAPI | undefined {\n return window.auroraview?.clipboard;\n }\n\n get shell(): ShellAPI | undefined {\n return window.auroraview?.shell;\n }\n\n get state(): AuroraViewState | undefined {\n return window.auroraview?.state;\n }\n}\n\n/** Singleton client instance */\nlet clientInstance: AuroraViewClient | null = null;\n\n/**\n * Create or get the AuroraView client instance\n */\nexport function createAuroraView(): AuroraViewClient {\n if (!clientInstance) {\n clientInstance = new AuroraViewClientImpl();\n }\n return clientInstance;\n}\n\n/**\n * Get the AuroraView client instance (alias for createAuroraView)\n */\nexport function getAuroraView(): AuroraViewClient {\n return createAuroraView();\n}\n","/**\n * Plugin utilities shared across all plugins\n */\n\n/**\n * Invoke a plugin command\n */\nexport async function invokePlugin<T = unknown>(\n plugin: string,\n command: string,\n args?: Record<string, unknown>\n): Promise<T> {\n if (!window.auroraview || !window.auroraview.invoke) {\n throw new Error('AuroraView bridge not available');\n }\n\n const result = await window.auroraview.invoke<T & { success?: boolean; error?: string; code?: string }>(\n `plugin:${plugin}|${command}`,\n args || {}\n );\n\n if (result && result.success === false) {\n const error = new Error(result.error || 'Unknown error') as Error & { code?: string };\n error.code = result.code || 'UNKNOWN';\n throw error;\n }\n\n return result;\n}\n\n/**\n * Attach a plugin to the auroraview object\n */\nexport function attachPlugin(name: string, api: Record<string, unknown>): void {\n if (window.auroraview) {\n (window.auroraview as unknown as Record<string, unknown>)[name] = api;\n console.log(`[AuroraView] ${name.charAt(0).toUpperCase() + name.slice(1)} plugin initialized`);\n }\n}\n\n/**\n * Wait for auroraview to be available and attach plugin\n */\nexport function initPlugin(name: string, api: Record<string, unknown>): void {\n if (window.auroraview) {\n attachPlugin(name, api);\n } else {\n const observer = setInterval(function () {\n if (window.auroraview) {\n clearInterval(observer);\n attachPlugin(name, api);\n }\n }, 10);\n\n // Stop trying after 5 seconds\n setTimeout(function () {\n clearInterval(observer);\n }, 5000);\n }\n}\n","/**\n * Interactive regions plugin for click-through windows\n *\n * This plugin monitors DOM elements with the `data-interactive` attribute\n * and reports their positions to the native layer for click-through support.\n *\n * @example\n * ```html\n * <!-- Mark an element as interactive -->\n * <button data-interactive>Click Me</button>\n *\n * <!-- The plugin will automatically track this element's position -->\n * ```\n *\n * @example\n * ```typescript\n * import { interactive } from 'auroraview-sdk';\n *\n * // Manually trigger a region update\n * interactive.update();\n *\n * // Get current regions\n * const regions = interactive.getRegions();\n *\n * // Enable/disable tracking\n * interactive.setEnabled(false);\n * ```\n */\n\nimport { invokePlugin, initPlugin } from './utils';\n\n/**\n * Interactive region data\n */\nexport interface InteractiveRegion {\n /** X coordinate (left edge) in pixels */\n x: number;\n /** Y coordinate (top edge) in pixels */\n y: number;\n /** Width in pixels */\n width: number;\n /** Height in pixels */\n height: number;\n /** Element ID (if available) */\n id?: string;\n}\n\n/**\n * Configuration for the interactive plugin\n */\nexport interface InteractiveConfig {\n /** Attribute name to look for (default: 'data-interactive') */\n attribute: string;\n /** Debounce delay in milliseconds (default: 100) */\n debounceMs: number;\n /** Whether to observe DOM changes (default: true) */\n observeChanges: boolean;\n /** Whether to observe resize events (default: true) */\n observeResize: boolean;\n /** Whether to observe scroll events (default: true) */\n observeScroll: boolean;\n}\n\nconst DEFAULT_CONFIG: InteractiveConfig = {\n attribute: 'data-interactive',\n debounceMs: 100,\n observeChanges: true,\n observeResize: true,\n observeScroll: true,\n};\n\nlet config: InteractiveConfig = { ...DEFAULT_CONFIG };\nlet enabled = true;\nlet observer: MutationObserver | null = null;\nlet resizeObserver: ResizeObserver | null = null;\nlet debounceTimer: ReturnType<typeof setTimeout> | null = null;\nlet lastRegions: InteractiveRegion[] = [];\n\n/**\n * Collect all interactive regions from the DOM\n */\nfunction collectRegions(): InteractiveRegion[] {\n const elements = document.querySelectorAll(`[${config.attribute}]`);\n const regions: InteractiveRegion[] = [];\n\n elements.forEach((element) => {\n const rect = element.getBoundingClientRect();\n\n // Skip invisible elements\n if (rect.width === 0 || rect.height === 0) {\n return;\n }\n\n // Skip elements outside viewport\n if (\n rect.bottom < 0 ||\n rect.top > window.innerHeight ||\n rect.right < 0 ||\n rect.left > window.innerWidth\n ) {\n return;\n }\n\n regions.push({\n x: Math.round(rect.left),\n y: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n id: element.id || undefined,\n });\n });\n\n return regions;\n}\n\n/**\n * Check if regions have changed\n */\nfunction regionsChanged(newRegions: InteractiveRegion[]): boolean {\n if (newRegions.length !== lastRegions.length) {\n return true;\n }\n\n for (let i = 0; i < newRegions.length; i++) {\n const a = newRegions[i];\n const b = lastRegions[i];\n if (a.x !== b.x || a.y !== b.y || a.width !== b.width || a.height !== b.height) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Send regions to native layer\n */\nasync function sendRegions(regions: InteractiveRegion[]): Promise<void> {\n try {\n await invokePlugin('window', 'update_interactive_regions', { regions });\n console.debug('[AuroraView] Updated interactive regions:', regions.length);\n } catch (error) {\n console.error('[AuroraView] Failed to update interactive regions:', error);\n }\n}\n\n/**\n * Update interactive regions (debounced)\n */\nfunction scheduleUpdate(): void {\n if (!enabled) return;\n\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n\n debounceTimer = setTimeout(() => {\n const regions = collectRegions();\n if (regionsChanged(regions)) {\n lastRegions = regions;\n sendRegions(regions);\n }\n }, config.debounceMs);\n}\n\n/**\n * Start observing DOM changes\n */\nfunction startObserving(): void {\n if (!config.observeChanges) return;\n\n // MutationObserver for DOM changes\n observer = new MutationObserver((mutations) => {\n // Check if any mutation affects interactive elements\n let needsUpdate = false;\n\n for (const mutation of mutations) {\n if (mutation.type === 'childList') {\n // Check added/removed nodes\n for (const node of mutation.addedNodes) {\n if (node instanceof Element && node.hasAttribute(config.attribute)) {\n needsUpdate = true;\n break;\n }\n }\n for (const node of mutation.removedNodes) {\n if (node instanceof Element && node.hasAttribute(config.attribute)) {\n needsUpdate = true;\n break;\n }\n }\n } else if (mutation.type === 'attributes') {\n if (mutation.attributeName === config.attribute) {\n needsUpdate = true;\n }\n }\n\n if (needsUpdate) break;\n }\n\n if (needsUpdate) {\n scheduleUpdate();\n }\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [config.attribute],\n });\n\n // ResizeObserver for element size changes\n if (config.observeResize) {\n resizeObserver = new ResizeObserver(() => {\n scheduleUpdate();\n });\n\n // Observe all interactive elements\n document.querySelectorAll(`[${config.attribute}]`).forEach((element) => {\n resizeObserver?.observe(element);\n });\n }\n\n // Window resize and scroll events\n if (config.observeResize) {\n window.addEventListener('resize', scheduleUpdate, { passive: true });\n }\n if (config.observeScroll) {\n window.addEventListener('scroll', scheduleUpdate, { passive: true });\n }\n}\n\n/**\n * Stop observing DOM changes\n */\nfunction stopObserving(): void {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n\n if (resizeObserver) {\n resizeObserver.disconnect();\n resizeObserver = null;\n }\n\n window.removeEventListener('resize', scheduleUpdate);\n window.removeEventListener('scroll', scheduleUpdate);\n\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n debounceTimer = null;\n }\n}\n\n/**\n * Interactive regions API\n */\nexport const interactive = {\n /**\n * Manually trigger a region update\n */\n update(): void {\n scheduleUpdate();\n },\n\n /**\n * Force immediate update (bypasses debounce)\n */\n forceUpdate(): void {\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n debounceTimer = null;\n }\n const regions = collectRegions();\n lastRegions = regions;\n sendRegions(regions);\n },\n\n /**\n * Get current interactive regions\n */\n getRegions(): InteractiveRegion[] {\n return collectRegions();\n },\n\n /**\n * Enable or disable tracking\n */\n setEnabled(value: boolean): void {\n enabled = value;\n if (enabled) {\n startObserving();\n scheduleUpdate();\n } else {\n stopObserving();\n // Clear regions when disabled\n lastRegions = [];\n sendRegions([]);\n }\n },\n\n /**\n * Check if tracking is enabled\n */\n isEnabled(): boolean {\n return enabled;\n },\n\n /**\n * Update configuration\n */\n configure(newConfig: Partial<InteractiveConfig>): void {\n const wasObserving = observer !== null;\n\n if (wasObserving) {\n stopObserving();\n }\n\n config = { ...config, ...newConfig };\n\n if (wasObserving && enabled) {\n startObserving();\n scheduleUpdate();\n }\n },\n\n /**\n * Get current configuration\n */\n getConfig(): InteractiveConfig {\n return { ...config };\n },\n\n /**\n * Initialize the plugin (called automatically)\n */\n init(): void {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n startObserving();\n scheduleUpdate();\n });\n } else {\n startObserving();\n scheduleUpdate();\n }\n },\n\n /**\n * Cleanup the plugin\n */\n destroy(): void {\n stopObserving();\n lastRegions = [];\n },\n};\n\n// Auto-initialize when loaded\ninitPlugin('interactive', interactive);\n\n// Start observing when DOM is ready\nif (typeof document !== 'undefined') {\n interactive.init();\n}\n\nexport default interactive;\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -58,4 +58,104 @@ declare class EventEmitter {
|
|
|
58
58
|
*/
|
|
59
59
|
declare function getGlobalEmitter(): EventEmitter;
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Interactive regions plugin for click-through windows
|
|
63
|
+
*
|
|
64
|
+
* This plugin monitors DOM elements with the `data-interactive` attribute
|
|
65
|
+
* and reports their positions to the native layer for click-through support.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```html
|
|
69
|
+
* <!-- Mark an element as interactive -->
|
|
70
|
+
* <button data-interactive>Click Me</button>
|
|
71
|
+
*
|
|
72
|
+
* <!-- The plugin will automatically track this element's position -->
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* import { interactive } from 'auroraview-sdk';
|
|
78
|
+
*
|
|
79
|
+
* // Manually trigger a region update
|
|
80
|
+
* interactive.update();
|
|
81
|
+
*
|
|
82
|
+
* // Get current regions
|
|
83
|
+
* const regions = interactive.getRegions();
|
|
84
|
+
*
|
|
85
|
+
* // Enable/disable tracking
|
|
86
|
+
* interactive.setEnabled(false);
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
/**
|
|
90
|
+
* Interactive region data
|
|
91
|
+
*/
|
|
92
|
+
interface InteractiveRegion {
|
|
93
|
+
/** X coordinate (left edge) in pixels */
|
|
94
|
+
x: number;
|
|
95
|
+
/** Y coordinate (top edge) in pixels */
|
|
96
|
+
y: number;
|
|
97
|
+
/** Width in pixels */
|
|
98
|
+
width: number;
|
|
99
|
+
/** Height in pixels */
|
|
100
|
+
height: number;
|
|
101
|
+
/** Element ID (if available) */
|
|
102
|
+
id?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Configuration for the interactive plugin
|
|
106
|
+
*/
|
|
107
|
+
interface InteractiveConfig {
|
|
108
|
+
/** Attribute name to look for (default: 'data-interactive') */
|
|
109
|
+
attribute: string;
|
|
110
|
+
/** Debounce delay in milliseconds (default: 100) */
|
|
111
|
+
debounceMs: number;
|
|
112
|
+
/** Whether to observe DOM changes (default: true) */
|
|
113
|
+
observeChanges: boolean;
|
|
114
|
+
/** Whether to observe resize events (default: true) */
|
|
115
|
+
observeResize: boolean;
|
|
116
|
+
/** Whether to observe scroll events (default: true) */
|
|
117
|
+
observeScroll: boolean;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Interactive regions API
|
|
121
|
+
*/
|
|
122
|
+
declare const interactive: {
|
|
123
|
+
/**
|
|
124
|
+
* Manually trigger a region update
|
|
125
|
+
*/
|
|
126
|
+
update(): void;
|
|
127
|
+
/**
|
|
128
|
+
* Force immediate update (bypasses debounce)
|
|
129
|
+
*/
|
|
130
|
+
forceUpdate(): void;
|
|
131
|
+
/**
|
|
132
|
+
* Get current interactive regions
|
|
133
|
+
*/
|
|
134
|
+
getRegions(): InteractiveRegion[];
|
|
135
|
+
/**
|
|
136
|
+
* Enable or disable tracking
|
|
137
|
+
*/
|
|
138
|
+
setEnabled(value: boolean): void;
|
|
139
|
+
/**
|
|
140
|
+
* Check if tracking is enabled
|
|
141
|
+
*/
|
|
142
|
+
isEnabled(): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Update configuration
|
|
145
|
+
*/
|
|
146
|
+
configure(newConfig: Partial<InteractiveConfig>): void;
|
|
147
|
+
/**
|
|
148
|
+
* Get current configuration
|
|
149
|
+
*/
|
|
150
|
+
getConfig(): InteractiveConfig;
|
|
151
|
+
/**
|
|
152
|
+
* Initialize the plugin (called automatically)
|
|
153
|
+
*/
|
|
154
|
+
init(): void;
|
|
155
|
+
/**
|
|
156
|
+
* Cleanup the plugin
|
|
157
|
+
*/
|
|
158
|
+
destroy(): void;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export { EventEmitter, EventHandler, type InteractiveConfig, type InteractiveRegion, Unsubscribe, getGlobalEmitter, interactive };
|
package/dist/index.d.ts
CHANGED
|
@@ -58,4 +58,104 @@ declare class EventEmitter {
|
|
|
58
58
|
*/
|
|
59
59
|
declare function getGlobalEmitter(): EventEmitter;
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Interactive regions plugin for click-through windows
|
|
63
|
+
*
|
|
64
|
+
* This plugin monitors DOM elements with the `data-interactive` attribute
|
|
65
|
+
* and reports their positions to the native layer for click-through support.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```html
|
|
69
|
+
* <!-- Mark an element as interactive -->
|
|
70
|
+
* <button data-interactive>Click Me</button>
|
|
71
|
+
*
|
|
72
|
+
* <!-- The plugin will automatically track this element's position -->
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* import { interactive } from 'auroraview-sdk';
|
|
78
|
+
*
|
|
79
|
+
* // Manually trigger a region update
|
|
80
|
+
* interactive.update();
|
|
81
|
+
*
|
|
82
|
+
* // Get current regions
|
|
83
|
+
* const regions = interactive.getRegions();
|
|
84
|
+
*
|
|
85
|
+
* // Enable/disable tracking
|
|
86
|
+
* interactive.setEnabled(false);
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
/**
|
|
90
|
+
* Interactive region data
|
|
91
|
+
*/
|
|
92
|
+
interface InteractiveRegion {
|
|
93
|
+
/** X coordinate (left edge) in pixels */
|
|
94
|
+
x: number;
|
|
95
|
+
/** Y coordinate (top edge) in pixels */
|
|
96
|
+
y: number;
|
|
97
|
+
/** Width in pixels */
|
|
98
|
+
width: number;
|
|
99
|
+
/** Height in pixels */
|
|
100
|
+
height: number;
|
|
101
|
+
/** Element ID (if available) */
|
|
102
|
+
id?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Configuration for the interactive plugin
|
|
106
|
+
*/
|
|
107
|
+
interface InteractiveConfig {
|
|
108
|
+
/** Attribute name to look for (default: 'data-interactive') */
|
|
109
|
+
attribute: string;
|
|
110
|
+
/** Debounce delay in milliseconds (default: 100) */
|
|
111
|
+
debounceMs: number;
|
|
112
|
+
/** Whether to observe DOM changes (default: true) */
|
|
113
|
+
observeChanges: boolean;
|
|
114
|
+
/** Whether to observe resize events (default: true) */
|
|
115
|
+
observeResize: boolean;
|
|
116
|
+
/** Whether to observe scroll events (default: true) */
|
|
117
|
+
observeScroll: boolean;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Interactive regions API
|
|
121
|
+
*/
|
|
122
|
+
declare const interactive: {
|
|
123
|
+
/**
|
|
124
|
+
* Manually trigger a region update
|
|
125
|
+
*/
|
|
126
|
+
update(): void;
|
|
127
|
+
/**
|
|
128
|
+
* Force immediate update (bypasses debounce)
|
|
129
|
+
*/
|
|
130
|
+
forceUpdate(): void;
|
|
131
|
+
/**
|
|
132
|
+
* Get current interactive regions
|
|
133
|
+
*/
|
|
134
|
+
getRegions(): InteractiveRegion[];
|
|
135
|
+
/**
|
|
136
|
+
* Enable or disable tracking
|
|
137
|
+
*/
|
|
138
|
+
setEnabled(value: boolean): void;
|
|
139
|
+
/**
|
|
140
|
+
* Check if tracking is enabled
|
|
141
|
+
*/
|
|
142
|
+
isEnabled(): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Update configuration
|
|
145
|
+
*/
|
|
146
|
+
configure(newConfig: Partial<InteractiveConfig>): void;
|
|
147
|
+
/**
|
|
148
|
+
* Get current configuration
|
|
149
|
+
*/
|
|
150
|
+
getConfig(): InteractiveConfig;
|
|
151
|
+
/**
|
|
152
|
+
* Initialize the plugin (called automatically)
|
|
153
|
+
*/
|
|
154
|
+
init(): void;
|
|
155
|
+
/**
|
|
156
|
+
* Cleanup the plugin
|
|
157
|
+
*/
|
|
158
|
+
destroy(): void;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export { EventEmitter, EventHandler, type InteractiveConfig, type InteractiveRegion, Unsubscribe, getGlobalEmitter, interactive };
|
package/dist/index.js
CHANGED
|
@@ -217,6 +217,271 @@ function getAuroraView() {
|
|
|
217
217
|
return createAuroraView();
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
|
|
220
|
+
// src/inject/plugins/utils.ts
|
|
221
|
+
async function invokePlugin(plugin, command, args) {
|
|
222
|
+
if (!window.auroraview || !window.auroraview.invoke) {
|
|
223
|
+
throw new Error("AuroraView bridge not available");
|
|
224
|
+
}
|
|
225
|
+
const result = await window.auroraview.invoke(
|
|
226
|
+
`plugin:${plugin}|${command}`,
|
|
227
|
+
args || {}
|
|
228
|
+
);
|
|
229
|
+
if (result && result.success === false) {
|
|
230
|
+
const error = new Error(result.error || "Unknown error");
|
|
231
|
+
error.code = result.code || "UNKNOWN";
|
|
232
|
+
throw error;
|
|
233
|
+
}
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
function attachPlugin(name, api) {
|
|
237
|
+
if (window.auroraview) {
|
|
238
|
+
window.auroraview[name] = api;
|
|
239
|
+
console.log(`[AuroraView] ${name.charAt(0).toUpperCase() + name.slice(1)} plugin initialized`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function initPlugin(name, api) {
|
|
243
|
+
if (window.auroraview) {
|
|
244
|
+
attachPlugin(name, api);
|
|
245
|
+
} else {
|
|
246
|
+
const observer2 = setInterval(function() {
|
|
247
|
+
if (window.auroraview) {
|
|
248
|
+
clearInterval(observer2);
|
|
249
|
+
attachPlugin(name, api);
|
|
250
|
+
}
|
|
251
|
+
}, 10);
|
|
252
|
+
setTimeout(function() {
|
|
253
|
+
clearInterval(observer2);
|
|
254
|
+
}, 5e3);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// src/inject/plugins/interactive.ts
|
|
259
|
+
var DEFAULT_CONFIG = {
|
|
260
|
+
attribute: "data-interactive",
|
|
261
|
+
debounceMs: 100,
|
|
262
|
+
observeChanges: true,
|
|
263
|
+
observeResize: true,
|
|
264
|
+
observeScroll: true
|
|
265
|
+
};
|
|
266
|
+
var config = { ...DEFAULT_CONFIG };
|
|
267
|
+
var enabled = true;
|
|
268
|
+
var observer = null;
|
|
269
|
+
var resizeObserver = null;
|
|
270
|
+
var debounceTimer = null;
|
|
271
|
+
var lastRegions = [];
|
|
272
|
+
function collectRegions() {
|
|
273
|
+
const elements = document.querySelectorAll(`[${config.attribute}]`);
|
|
274
|
+
const regions = [];
|
|
275
|
+
elements.forEach((element) => {
|
|
276
|
+
const rect = element.getBoundingClientRect();
|
|
277
|
+
if (rect.width === 0 || rect.height === 0) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (rect.bottom < 0 || rect.top > window.innerHeight || rect.right < 0 || rect.left > window.innerWidth) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
regions.push({
|
|
284
|
+
x: Math.round(rect.left),
|
|
285
|
+
y: Math.round(rect.top),
|
|
286
|
+
width: Math.round(rect.width),
|
|
287
|
+
height: Math.round(rect.height),
|
|
288
|
+
id: element.id || void 0
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
return regions;
|
|
292
|
+
}
|
|
293
|
+
function regionsChanged(newRegions) {
|
|
294
|
+
if (newRegions.length !== lastRegions.length) {
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
for (let i = 0; i < newRegions.length; i++) {
|
|
298
|
+
const a = newRegions[i];
|
|
299
|
+
const b = lastRegions[i];
|
|
300
|
+
if (a.x !== b.x || a.y !== b.y || a.width !== b.width || a.height !== b.height) {
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
async function sendRegions(regions) {
|
|
307
|
+
try {
|
|
308
|
+
await invokePlugin("window", "update_interactive_regions", { regions });
|
|
309
|
+
console.debug("[AuroraView] Updated interactive regions:", regions.length);
|
|
310
|
+
} catch (error) {
|
|
311
|
+
console.error("[AuroraView] Failed to update interactive regions:", error);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function scheduleUpdate() {
|
|
315
|
+
if (!enabled) return;
|
|
316
|
+
if (debounceTimer) {
|
|
317
|
+
clearTimeout(debounceTimer);
|
|
318
|
+
}
|
|
319
|
+
debounceTimer = setTimeout(() => {
|
|
320
|
+
const regions = collectRegions();
|
|
321
|
+
if (regionsChanged(regions)) {
|
|
322
|
+
lastRegions = regions;
|
|
323
|
+
sendRegions(regions);
|
|
324
|
+
}
|
|
325
|
+
}, config.debounceMs);
|
|
326
|
+
}
|
|
327
|
+
function startObserving() {
|
|
328
|
+
if (!config.observeChanges) return;
|
|
329
|
+
observer = new MutationObserver((mutations) => {
|
|
330
|
+
let needsUpdate = false;
|
|
331
|
+
for (const mutation of mutations) {
|
|
332
|
+
if (mutation.type === "childList") {
|
|
333
|
+
for (const node of mutation.addedNodes) {
|
|
334
|
+
if (node instanceof Element && node.hasAttribute(config.attribute)) {
|
|
335
|
+
needsUpdate = true;
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
for (const node of mutation.removedNodes) {
|
|
340
|
+
if (node instanceof Element && node.hasAttribute(config.attribute)) {
|
|
341
|
+
needsUpdate = true;
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
} else if (mutation.type === "attributes") {
|
|
346
|
+
if (mutation.attributeName === config.attribute) {
|
|
347
|
+
needsUpdate = true;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (needsUpdate) break;
|
|
351
|
+
}
|
|
352
|
+
if (needsUpdate) {
|
|
353
|
+
scheduleUpdate();
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
observer.observe(document.body, {
|
|
357
|
+
childList: true,
|
|
358
|
+
subtree: true,
|
|
359
|
+
attributes: true,
|
|
360
|
+
attributeFilter: [config.attribute]
|
|
361
|
+
});
|
|
362
|
+
if (config.observeResize) {
|
|
363
|
+
resizeObserver = new ResizeObserver(() => {
|
|
364
|
+
scheduleUpdate();
|
|
365
|
+
});
|
|
366
|
+
document.querySelectorAll(`[${config.attribute}]`).forEach((element) => {
|
|
367
|
+
resizeObserver?.observe(element);
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
if (config.observeResize) {
|
|
371
|
+
window.addEventListener("resize", scheduleUpdate, { passive: true });
|
|
372
|
+
}
|
|
373
|
+
if (config.observeScroll) {
|
|
374
|
+
window.addEventListener("scroll", scheduleUpdate, { passive: true });
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
function stopObserving() {
|
|
378
|
+
if (observer) {
|
|
379
|
+
observer.disconnect();
|
|
380
|
+
observer = null;
|
|
381
|
+
}
|
|
382
|
+
if (resizeObserver) {
|
|
383
|
+
resizeObserver.disconnect();
|
|
384
|
+
resizeObserver = null;
|
|
385
|
+
}
|
|
386
|
+
window.removeEventListener("resize", scheduleUpdate);
|
|
387
|
+
window.removeEventListener("scroll", scheduleUpdate);
|
|
388
|
+
if (debounceTimer) {
|
|
389
|
+
clearTimeout(debounceTimer);
|
|
390
|
+
debounceTimer = null;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
var interactive = {
|
|
394
|
+
/**
|
|
395
|
+
* Manually trigger a region update
|
|
396
|
+
*/
|
|
397
|
+
update() {
|
|
398
|
+
scheduleUpdate();
|
|
399
|
+
},
|
|
400
|
+
/**
|
|
401
|
+
* Force immediate update (bypasses debounce)
|
|
402
|
+
*/
|
|
403
|
+
forceUpdate() {
|
|
404
|
+
if (debounceTimer) {
|
|
405
|
+
clearTimeout(debounceTimer);
|
|
406
|
+
debounceTimer = null;
|
|
407
|
+
}
|
|
408
|
+
const regions = collectRegions();
|
|
409
|
+
lastRegions = regions;
|
|
410
|
+
sendRegions(regions);
|
|
411
|
+
},
|
|
412
|
+
/**
|
|
413
|
+
* Get current interactive regions
|
|
414
|
+
*/
|
|
415
|
+
getRegions() {
|
|
416
|
+
return collectRegions();
|
|
417
|
+
},
|
|
418
|
+
/**
|
|
419
|
+
* Enable or disable tracking
|
|
420
|
+
*/
|
|
421
|
+
setEnabled(value) {
|
|
422
|
+
enabled = value;
|
|
423
|
+
if (enabled) {
|
|
424
|
+
startObserving();
|
|
425
|
+
scheduleUpdate();
|
|
426
|
+
} else {
|
|
427
|
+
stopObserving();
|
|
428
|
+
lastRegions = [];
|
|
429
|
+
sendRegions([]);
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
/**
|
|
433
|
+
* Check if tracking is enabled
|
|
434
|
+
*/
|
|
435
|
+
isEnabled() {
|
|
436
|
+
return enabled;
|
|
437
|
+
},
|
|
438
|
+
/**
|
|
439
|
+
* Update configuration
|
|
440
|
+
*/
|
|
441
|
+
configure(newConfig) {
|
|
442
|
+
const wasObserving = observer !== null;
|
|
443
|
+
if (wasObserving) {
|
|
444
|
+
stopObserving();
|
|
445
|
+
}
|
|
446
|
+
config = { ...config, ...newConfig };
|
|
447
|
+
if (wasObserving && enabled) {
|
|
448
|
+
startObserving();
|
|
449
|
+
scheduleUpdate();
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
/**
|
|
453
|
+
* Get current configuration
|
|
454
|
+
*/
|
|
455
|
+
getConfig() {
|
|
456
|
+
return { ...config };
|
|
457
|
+
},
|
|
458
|
+
/**
|
|
459
|
+
* Initialize the plugin (called automatically)
|
|
460
|
+
*/
|
|
461
|
+
init() {
|
|
462
|
+
if (document.readyState === "loading") {
|
|
463
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
464
|
+
startObserving();
|
|
465
|
+
scheduleUpdate();
|
|
466
|
+
});
|
|
467
|
+
} else {
|
|
468
|
+
startObserving();
|
|
469
|
+
scheduleUpdate();
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
/**
|
|
473
|
+
* Cleanup the plugin
|
|
474
|
+
*/
|
|
475
|
+
destroy() {
|
|
476
|
+
stopObserving();
|
|
477
|
+
lastRegions = [];
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
initPlugin("interactive", interactive);
|
|
481
|
+
if (typeof document !== "undefined") {
|
|
482
|
+
interactive.init();
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export { EventEmitter, createAuroraView, getAuroraView, getGlobalEmitter, interactive };
|
|
221
486
|
//# sourceMappingURL=index.js.map
|
|
222
487
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/events.ts","../src/core/bridge.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * AuroraView SDK Event System\n *\n * Provides a type-safe event emitter with proper unsubscribe support.\n */\n\nimport type { EventHandler, Unsubscribe } from './types';\n\n/**\n * Event emitter with unsubscribe support\n */\nexport class EventEmitter {\n private handlers = new Map<string, Set<EventHandler>>();\n\n /**\n * Subscribe to an event\n * @param event - Event name\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n const handlers = this.handlers.get(event)!;\n handlers.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => {\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n this.handlers.delete(event);\n }\n };\n }\n\n /**\n * Subscribe to an event once\n * @param event - Event name\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n const wrapper: EventHandler<T> = (data) => {\n unsubscribe();\n handler(data);\n };\n const unsubscribe = this.on(event, wrapper);\n return unsubscribe;\n }\n\n /**\n * Emit an event to all handlers\n * @param event - Event name\n * @param data - Event data\n */\n emit<T = unknown>(event: string, data: T): void {\n const handlers = this.handlers.get(event);\n if (!handlers) return;\n\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (e) {\n console.error(`[AuroraView] Error in event handler for \"${event}\":`, e);\n }\n });\n }\n\n /**\n * Remove event handler(s)\n * @param event - Event name\n * @param handler - Optional specific handler to remove\n */\n off(event: string, handler?: EventHandler): void {\n if (handler) {\n this.handlers.get(event)?.delete(handler);\n } else {\n this.handlers.delete(event);\n }\n }\n\n /**\n * Check if event has handlers\n * @param event - Event name\n */\n hasHandlers(event: string): boolean {\n const handlers = this.handlers.get(event);\n return handlers !== undefined && handlers.size > 0;\n }\n\n /**\n * Get handler count for an event\n * @param event - Event name\n */\n handlerCount(event: string): number {\n return this.handlers.get(event)?.size ?? 0;\n }\n\n /**\n * Remove all handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n/** Singleton event emitter instance */\nlet globalEmitter: EventEmitter | null = null;\n\n/**\n * Get the global event emitter instance\n */\nexport function getGlobalEmitter(): EventEmitter {\n if (!globalEmitter) {\n globalEmitter = new EventEmitter();\n }\n return globalEmitter;\n}\n","/**\n * AuroraView SDK Bridge Client\n *\n * Provides a type-safe wrapper around the native bridge API.\n */\n\nimport { EventEmitter, getGlobalEmitter } from './events';\nimport type {\n EventHandler,\n Unsubscribe,\n AuroraViewBridge,\n FileSystemAPI,\n DialogAPI,\n ClipboardAPI,\n ShellAPI,\n AuroraViewState,\n} from './types';\n\n/**\n * AuroraView client interface\n */\nexport interface AuroraViewClient {\n /** Call a Python method (RPC-style) */\n call<T = unknown>(method: string, params?: unknown): Promise<T>;\n\n /** Invoke a plugin command */\n invoke<T = unknown>(cmd: string, args?: Record<string, unknown>): Promise<T>;\n\n /** Send an event to Python (fire-and-forget) */\n emit(event: string, data?: unknown): void;\n\n /** Subscribe to an event from Python */\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe;\n\n /** Subscribe to an event once */\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe;\n\n /** Unsubscribe from an event */\n off(event: string, handler?: EventHandler): void;\n\n /** Check if bridge is ready */\n isReady(): boolean;\n\n /** Wait for bridge to be ready */\n whenReady(): Promise<AuroraViewClient>;\n\n /** Get the raw bridge object */\n getRawBridge(): AuroraViewBridge | undefined;\n\n /** File system API */\n readonly fs: FileSystemAPI | undefined;\n\n /** Dialog API */\n readonly dialog: DialogAPI | undefined;\n\n /** Clipboard API */\n readonly clipboard: ClipboardAPI | undefined;\n\n /** Shell API */\n readonly shell: ShellAPI | undefined;\n\n /** Shared state */\n readonly state: AuroraViewState | undefined;\n}\n\n/**\n * Internal client implementation\n */\nclass AuroraViewClientImpl implements AuroraViewClient {\n private events: EventEmitter;\n private interceptInstalled = false;\n\n constructor() {\n this.events = getGlobalEmitter();\n this.installTriggerIntercept();\n }\n\n /**\n * Install intercept on window.auroraview.trigger to forward events\n */\n private installTriggerIntercept(): void {\n if (this.interceptInstalled) return;\n if (typeof window === 'undefined') return;\n\n const install = () => {\n const bridge = window.auroraview;\n if (!bridge) return;\n\n const originalTrigger = bridge.trigger;\n bridge.trigger = (event: string, detail?: unknown) => {\n // Call original trigger first\n originalTrigger?.call(bridge, event, detail);\n // Forward to our event system\n this.events.emit(event, detail);\n };\n\n this.interceptInstalled = true;\n };\n\n // Try to install immediately\n if (window.auroraview) {\n install();\n } else {\n // Wait for bridge to be available\n const checkInterval = setInterval(() => {\n if (window.auroraview) {\n clearInterval(checkInterval);\n install();\n }\n }, 10);\n\n // Stop checking after 10 seconds\n setTimeout(() => clearInterval(checkInterval), 10000);\n }\n }\n\n call<T = unknown>(method: string, params?: unknown): Promise<T> {\n const bridge = window.auroraview;\n if (!bridge) {\n return Promise.reject(new Error('AuroraView bridge not available'));\n }\n return bridge.call<T>(method, params);\n }\n\n invoke<T = unknown>(cmd: string, args?: Record<string, unknown>): Promise<T> {\n const bridge = window.auroraview;\n if (!bridge) {\n return Promise.reject(new Error('AuroraView bridge not available'));\n }\n return bridge.invoke<T>(cmd, args);\n }\n\n emit(event: string, data?: unknown): void {\n const bridge = window.auroraview;\n if (bridge) {\n bridge.send_event(event, data);\n }\n }\n\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n return this.events.on(event, handler);\n }\n\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n return this.events.once(event, handler);\n }\n\n off(event: string, handler?: EventHandler): void {\n this.events.off(event, handler);\n }\n\n isReady(): boolean {\n return window.auroraview?._ready === true;\n }\n\n whenReady(): Promise<AuroraViewClient> {\n return new Promise((resolve) => {\n if (this.isReady()) {\n resolve(this);\n } else if (window.auroraview) {\n window.auroraview.whenReady().then(() => {\n this.installTriggerIntercept();\n resolve(this);\n });\n } else {\n // Wait for bridge to appear\n const checkInterval = setInterval(() => {\n if (window.auroraview) {\n clearInterval(checkInterval);\n window.auroraview.whenReady().then(() => {\n this.installTriggerIntercept();\n resolve(this);\n });\n }\n }, 10);\n\n // Timeout after 30 seconds\n setTimeout(() => {\n clearInterval(checkInterval);\n resolve(this);\n }, 30000);\n }\n });\n }\n\n getRawBridge(): AuroraViewBridge | undefined {\n return window.auroraview;\n }\n\n get fs(): FileSystemAPI | undefined {\n return window.auroraview?.fs;\n }\n\n get dialog(): DialogAPI | undefined {\n return window.auroraview?.dialog;\n }\n\n get clipboard(): ClipboardAPI | undefined {\n return window.auroraview?.clipboard;\n }\n\n get shell(): ShellAPI | undefined {\n return window.auroraview?.shell;\n }\n\n get state(): AuroraViewState | undefined {\n return window.auroraview?.state;\n }\n}\n\n/** Singleton client instance */\nlet clientInstance: AuroraViewClient | null = null;\n\n/**\n * Create or get the AuroraView client instance\n */\nexport function createAuroraView(): AuroraViewClient {\n if (!clientInstance) {\n clientInstance = new AuroraViewClientImpl();\n }\n return clientInstance;\n}\n\n/**\n * Get the AuroraView client instance (alias for createAuroraView)\n */\nexport function getAuroraView(): AuroraViewClient {\n return createAuroraView();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/events.ts","../src/core/bridge.ts","../src/inject/plugins/utils.ts","../src/inject/plugins/interactive.ts"],"names":["observer"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * AuroraView SDK Event System\n *\n * Provides a type-safe event emitter with proper unsubscribe support.\n */\n\nimport type { EventHandler, Unsubscribe } from './types';\n\n/**\n * Event emitter with unsubscribe support\n */\nexport class EventEmitter {\n private handlers = new Map<string, Set<EventHandler>>();\n\n /**\n * Subscribe to an event\n * @param event - Event name\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n const handlers = this.handlers.get(event)!;\n handlers.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => {\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n this.handlers.delete(event);\n }\n };\n }\n\n /**\n * Subscribe to an event once\n * @param event - Event name\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n const wrapper: EventHandler<T> = (data) => {\n unsubscribe();\n handler(data);\n };\n const unsubscribe = this.on(event, wrapper);\n return unsubscribe;\n }\n\n /**\n * Emit an event to all handlers\n * @param event - Event name\n * @param data - Event data\n */\n emit<T = unknown>(event: string, data: T): void {\n const handlers = this.handlers.get(event);\n if (!handlers) return;\n\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (e) {\n console.error(`[AuroraView] Error in event handler for \"${event}\":`, e);\n }\n });\n }\n\n /**\n * Remove event handler(s)\n * @param event - Event name\n * @param handler - Optional specific handler to remove\n */\n off(event: string, handler?: EventHandler): void {\n if (handler) {\n this.handlers.get(event)?.delete(handler);\n } else {\n this.handlers.delete(event);\n }\n }\n\n /**\n * Check if event has handlers\n * @param event - Event name\n */\n hasHandlers(event: string): boolean {\n const handlers = this.handlers.get(event);\n return handlers !== undefined && handlers.size > 0;\n }\n\n /**\n * Get handler count for an event\n * @param event - Event name\n */\n handlerCount(event: string): number {\n return this.handlers.get(event)?.size ?? 0;\n }\n\n /**\n * Remove all handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n/** Singleton event emitter instance */\nlet globalEmitter: EventEmitter | null = null;\n\n/**\n * Get the global event emitter instance\n */\nexport function getGlobalEmitter(): EventEmitter {\n if (!globalEmitter) {\n globalEmitter = new EventEmitter();\n }\n return globalEmitter;\n}\n","/**\n * AuroraView SDK Bridge Client\n *\n * Provides a type-safe wrapper around the native bridge API.\n */\n\nimport { EventEmitter, getGlobalEmitter } from './events';\nimport type {\n EventHandler,\n Unsubscribe,\n AuroraViewBridge,\n FileSystemAPI,\n DialogAPI,\n ClipboardAPI,\n ShellAPI,\n AuroraViewState,\n} from './types';\n\n/**\n * AuroraView client interface\n */\nexport interface AuroraViewClient {\n /** Call a Python method (RPC-style) */\n call<T = unknown>(method: string, params?: unknown): Promise<T>;\n\n /** Invoke a plugin command */\n invoke<T = unknown>(cmd: string, args?: Record<string, unknown>): Promise<T>;\n\n /** Send an event to Python (fire-and-forget) */\n emit(event: string, data?: unknown): void;\n\n /** Subscribe to an event from Python */\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe;\n\n /** Subscribe to an event once */\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe;\n\n /** Unsubscribe from an event */\n off(event: string, handler?: EventHandler): void;\n\n /** Check if bridge is ready */\n isReady(): boolean;\n\n /** Wait for bridge to be ready */\n whenReady(): Promise<AuroraViewClient>;\n\n /** Get the raw bridge object */\n getRawBridge(): AuroraViewBridge | undefined;\n\n /** File system API */\n readonly fs: FileSystemAPI | undefined;\n\n /** Dialog API */\n readonly dialog: DialogAPI | undefined;\n\n /** Clipboard API */\n readonly clipboard: ClipboardAPI | undefined;\n\n /** Shell API */\n readonly shell: ShellAPI | undefined;\n\n /** Shared state */\n readonly state: AuroraViewState | undefined;\n}\n\n/**\n * Internal client implementation\n */\nclass AuroraViewClientImpl implements AuroraViewClient {\n private events: EventEmitter;\n private interceptInstalled = false;\n\n constructor() {\n this.events = getGlobalEmitter();\n this.installTriggerIntercept();\n }\n\n /**\n * Install intercept on window.auroraview.trigger to forward events\n */\n private installTriggerIntercept(): void {\n if (this.interceptInstalled) return;\n if (typeof window === 'undefined') return;\n\n const install = () => {\n const bridge = window.auroraview;\n if (!bridge) return;\n\n const originalTrigger = bridge.trigger;\n bridge.trigger = (event: string, detail?: unknown) => {\n // Call original trigger first\n originalTrigger?.call(bridge, event, detail);\n // Forward to our event system\n this.events.emit(event, detail);\n };\n\n this.interceptInstalled = true;\n };\n\n // Try to install immediately\n if (window.auroraview) {\n install();\n } else {\n // Wait for bridge to be available\n const checkInterval = setInterval(() => {\n if (window.auroraview) {\n clearInterval(checkInterval);\n install();\n }\n }, 10);\n\n // Stop checking after 10 seconds\n setTimeout(() => clearInterval(checkInterval), 10000);\n }\n }\n\n call<T = unknown>(method: string, params?: unknown): Promise<T> {\n const bridge = window.auroraview;\n if (!bridge) {\n return Promise.reject(new Error('AuroraView bridge not available'));\n }\n return bridge.call<T>(method, params);\n }\n\n invoke<T = unknown>(cmd: string, args?: Record<string, unknown>): Promise<T> {\n const bridge = window.auroraview;\n if (!bridge) {\n return Promise.reject(new Error('AuroraView bridge not available'));\n }\n return bridge.invoke<T>(cmd, args);\n }\n\n emit(event: string, data?: unknown): void {\n const bridge = window.auroraview;\n if (bridge) {\n bridge.send_event(event, data);\n }\n }\n\n on<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n return this.events.on(event, handler);\n }\n\n once<T = unknown>(event: string, handler: EventHandler<T>): Unsubscribe {\n return this.events.once(event, handler);\n }\n\n off(event: string, handler?: EventHandler): void {\n this.events.off(event, handler);\n }\n\n isReady(): boolean {\n return window.auroraview?._ready === true;\n }\n\n whenReady(): Promise<AuroraViewClient> {\n return new Promise((resolve) => {\n if (this.isReady()) {\n resolve(this);\n } else if (window.auroraview) {\n window.auroraview.whenReady().then(() => {\n this.installTriggerIntercept();\n resolve(this);\n });\n } else {\n // Wait for bridge to appear\n const checkInterval = setInterval(() => {\n if (window.auroraview) {\n clearInterval(checkInterval);\n window.auroraview.whenReady().then(() => {\n this.installTriggerIntercept();\n resolve(this);\n });\n }\n }, 10);\n\n // Timeout after 30 seconds\n setTimeout(() => {\n clearInterval(checkInterval);\n resolve(this);\n }, 30000);\n }\n });\n }\n\n getRawBridge(): AuroraViewBridge | undefined {\n return window.auroraview;\n }\n\n get fs(): FileSystemAPI | undefined {\n return window.auroraview?.fs;\n }\n\n get dialog(): DialogAPI | undefined {\n return window.auroraview?.dialog;\n }\n\n get clipboard(): ClipboardAPI | undefined {\n return window.auroraview?.clipboard;\n }\n\n get shell(): ShellAPI | undefined {\n return window.auroraview?.shell;\n }\n\n get state(): AuroraViewState | undefined {\n return window.auroraview?.state;\n }\n}\n\n/** Singleton client instance */\nlet clientInstance: AuroraViewClient | null = null;\n\n/**\n * Create or get the AuroraView client instance\n */\nexport function createAuroraView(): AuroraViewClient {\n if (!clientInstance) {\n clientInstance = new AuroraViewClientImpl();\n }\n return clientInstance;\n}\n\n/**\n * Get the AuroraView client instance (alias for createAuroraView)\n */\nexport function getAuroraView(): AuroraViewClient {\n return createAuroraView();\n}\n","/**\n * Plugin utilities shared across all plugins\n */\n\n/**\n * Invoke a plugin command\n */\nexport async function invokePlugin<T = unknown>(\n plugin: string,\n command: string,\n args?: Record<string, unknown>\n): Promise<T> {\n if (!window.auroraview || !window.auroraview.invoke) {\n throw new Error('AuroraView bridge not available');\n }\n\n const result = await window.auroraview.invoke<T & { success?: boolean; error?: string; code?: string }>(\n `plugin:${plugin}|${command}`,\n args || {}\n );\n\n if (result && result.success === false) {\n const error = new Error(result.error || 'Unknown error') as Error & { code?: string };\n error.code = result.code || 'UNKNOWN';\n throw error;\n }\n\n return result;\n}\n\n/**\n * Attach a plugin to the auroraview object\n */\nexport function attachPlugin(name: string, api: Record<string, unknown>): void {\n if (window.auroraview) {\n (window.auroraview as unknown as Record<string, unknown>)[name] = api;\n console.log(`[AuroraView] ${name.charAt(0).toUpperCase() + name.slice(1)} plugin initialized`);\n }\n}\n\n/**\n * Wait for auroraview to be available and attach plugin\n */\nexport function initPlugin(name: string, api: Record<string, unknown>): void {\n if (window.auroraview) {\n attachPlugin(name, api);\n } else {\n const observer = setInterval(function () {\n if (window.auroraview) {\n clearInterval(observer);\n attachPlugin(name, api);\n }\n }, 10);\n\n // Stop trying after 5 seconds\n setTimeout(function () {\n clearInterval(observer);\n }, 5000);\n }\n}\n","/**\n * Interactive regions plugin for click-through windows\n *\n * This plugin monitors DOM elements with the `data-interactive` attribute\n * and reports their positions to the native layer for click-through support.\n *\n * @example\n * ```html\n * <!-- Mark an element as interactive -->\n * <button data-interactive>Click Me</button>\n *\n * <!-- The plugin will automatically track this element's position -->\n * ```\n *\n * @example\n * ```typescript\n * import { interactive } from 'auroraview-sdk';\n *\n * // Manually trigger a region update\n * interactive.update();\n *\n * // Get current regions\n * const regions = interactive.getRegions();\n *\n * // Enable/disable tracking\n * interactive.setEnabled(false);\n * ```\n */\n\nimport { invokePlugin, initPlugin } from './utils';\n\n/**\n * Interactive region data\n */\nexport interface InteractiveRegion {\n /** X coordinate (left edge) in pixels */\n x: number;\n /** Y coordinate (top edge) in pixels */\n y: number;\n /** Width in pixels */\n width: number;\n /** Height in pixels */\n height: number;\n /** Element ID (if available) */\n id?: string;\n}\n\n/**\n * Configuration for the interactive plugin\n */\nexport interface InteractiveConfig {\n /** Attribute name to look for (default: 'data-interactive') */\n attribute: string;\n /** Debounce delay in milliseconds (default: 100) */\n debounceMs: number;\n /** Whether to observe DOM changes (default: true) */\n observeChanges: boolean;\n /** Whether to observe resize events (default: true) */\n observeResize: boolean;\n /** Whether to observe scroll events (default: true) */\n observeScroll: boolean;\n}\n\nconst DEFAULT_CONFIG: InteractiveConfig = {\n attribute: 'data-interactive',\n debounceMs: 100,\n observeChanges: true,\n observeResize: true,\n observeScroll: true,\n};\n\nlet config: InteractiveConfig = { ...DEFAULT_CONFIG };\nlet enabled = true;\nlet observer: MutationObserver | null = null;\nlet resizeObserver: ResizeObserver | null = null;\nlet debounceTimer: ReturnType<typeof setTimeout> | null = null;\nlet lastRegions: InteractiveRegion[] = [];\n\n/**\n * Collect all interactive regions from the DOM\n */\nfunction collectRegions(): InteractiveRegion[] {\n const elements = document.querySelectorAll(`[${config.attribute}]`);\n const regions: InteractiveRegion[] = [];\n\n elements.forEach((element) => {\n const rect = element.getBoundingClientRect();\n\n // Skip invisible elements\n if (rect.width === 0 || rect.height === 0) {\n return;\n }\n\n // Skip elements outside viewport\n if (\n rect.bottom < 0 ||\n rect.top > window.innerHeight ||\n rect.right < 0 ||\n rect.left > window.innerWidth\n ) {\n return;\n }\n\n regions.push({\n x: Math.round(rect.left),\n y: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n id: element.id || undefined,\n });\n });\n\n return regions;\n}\n\n/**\n * Check if regions have changed\n */\nfunction regionsChanged(newRegions: InteractiveRegion[]): boolean {\n if (newRegions.length !== lastRegions.length) {\n return true;\n }\n\n for (let i = 0; i < newRegions.length; i++) {\n const a = newRegions[i];\n const b = lastRegions[i];\n if (a.x !== b.x || a.y !== b.y || a.width !== b.width || a.height !== b.height) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Send regions to native layer\n */\nasync function sendRegions(regions: InteractiveRegion[]): Promise<void> {\n try {\n await invokePlugin('window', 'update_interactive_regions', { regions });\n console.debug('[AuroraView] Updated interactive regions:', regions.length);\n } catch (error) {\n console.error('[AuroraView] Failed to update interactive regions:', error);\n }\n}\n\n/**\n * Update interactive regions (debounced)\n */\nfunction scheduleUpdate(): void {\n if (!enabled) return;\n\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n\n debounceTimer = setTimeout(() => {\n const regions = collectRegions();\n if (regionsChanged(regions)) {\n lastRegions = regions;\n sendRegions(regions);\n }\n }, config.debounceMs);\n}\n\n/**\n * Start observing DOM changes\n */\nfunction startObserving(): void {\n if (!config.observeChanges) return;\n\n // MutationObserver for DOM changes\n observer = new MutationObserver((mutations) => {\n // Check if any mutation affects interactive elements\n let needsUpdate = false;\n\n for (const mutation of mutations) {\n if (mutation.type === 'childList') {\n // Check added/removed nodes\n for (const node of mutation.addedNodes) {\n if (node instanceof Element && node.hasAttribute(config.attribute)) {\n needsUpdate = true;\n break;\n }\n }\n for (const node of mutation.removedNodes) {\n if (node instanceof Element && node.hasAttribute(config.attribute)) {\n needsUpdate = true;\n break;\n }\n }\n } else if (mutation.type === 'attributes') {\n if (mutation.attributeName === config.attribute) {\n needsUpdate = true;\n }\n }\n\n if (needsUpdate) break;\n }\n\n if (needsUpdate) {\n scheduleUpdate();\n }\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [config.attribute],\n });\n\n // ResizeObserver for element size changes\n if (config.observeResize) {\n resizeObserver = new ResizeObserver(() => {\n scheduleUpdate();\n });\n\n // Observe all interactive elements\n document.querySelectorAll(`[${config.attribute}]`).forEach((element) => {\n resizeObserver?.observe(element);\n });\n }\n\n // Window resize and scroll events\n if (config.observeResize) {\n window.addEventListener('resize', scheduleUpdate, { passive: true });\n }\n if (config.observeScroll) {\n window.addEventListener('scroll', scheduleUpdate, { passive: true });\n }\n}\n\n/**\n * Stop observing DOM changes\n */\nfunction stopObserving(): void {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n\n if (resizeObserver) {\n resizeObserver.disconnect();\n resizeObserver = null;\n }\n\n window.removeEventListener('resize', scheduleUpdate);\n window.removeEventListener('scroll', scheduleUpdate);\n\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n debounceTimer = null;\n }\n}\n\n/**\n * Interactive regions API\n */\nexport const interactive = {\n /**\n * Manually trigger a region update\n */\n update(): void {\n scheduleUpdate();\n },\n\n /**\n * Force immediate update (bypasses debounce)\n */\n forceUpdate(): void {\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n debounceTimer = null;\n }\n const regions = collectRegions();\n lastRegions = regions;\n sendRegions(regions);\n },\n\n /**\n * Get current interactive regions\n */\n getRegions(): InteractiveRegion[] {\n return collectRegions();\n },\n\n /**\n * Enable or disable tracking\n */\n setEnabled(value: boolean): void {\n enabled = value;\n if (enabled) {\n startObserving();\n scheduleUpdate();\n } else {\n stopObserving();\n // Clear regions when disabled\n lastRegions = [];\n sendRegions([]);\n }\n },\n\n /**\n * Check if tracking is enabled\n */\n isEnabled(): boolean {\n return enabled;\n },\n\n /**\n * Update configuration\n */\n configure(newConfig: Partial<InteractiveConfig>): void {\n const wasObserving = observer !== null;\n\n if (wasObserving) {\n stopObserving();\n }\n\n config = { ...config, ...newConfig };\n\n if (wasObserving && enabled) {\n startObserving();\n scheduleUpdate();\n }\n },\n\n /**\n * Get current configuration\n */\n getConfig(): InteractiveConfig {\n return { ...config };\n },\n\n /**\n * Initialize the plugin (called automatically)\n */\n init(): void {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n startObserving();\n scheduleUpdate();\n });\n } else {\n startObserving();\n scheduleUpdate();\n }\n },\n\n /**\n * Cleanup the plugin\n */\n destroy(): void {\n stopObserving();\n lastRegions = [];\n },\n};\n\n// Auto-initialize when loaded\ninitPlugin('interactive', interactive);\n\n// Start observing when DOM is ready\nif (typeof document !== 'undefined') {\n interactive.init();\n}\n\nexport default interactive;\n"]}
|