asyar-sdk 1.17.1 → 2.0.0
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/README.md +95 -42
- package/dist/ExtensionBridge.d.ts +1 -1
- package/dist/ExtensionBridge.d.ts.map +1 -1
- package/dist/ExtensionBridge.js +17 -13
- package/dist/ExtensionBridge.js.map +1 -1
- package/dist/ExtensionBridge.test.js +76 -101
- package/dist/ExtensionBridge.test.js.map +1 -1
- package/dist/ExtensionContext.d.ts +22 -57
- package/dist/ExtensionContext.d.ts.map +1 -1
- package/dist/ExtensionContext.js +84 -205
- package/dist/ExtensionContext.js.map +1 -1
- package/dist/ExtensionContext.test.js +91 -66
- package/dist/ExtensionContext.test.js.map +1 -1
- package/dist/ExtensionContextCore.d.ts +46 -0
- package/dist/ExtensionContextCore.d.ts.map +1 -0
- package/dist/ExtensionContextCore.js +149 -0
- package/dist/ExtensionContextCore.js.map +1 -0
- package/dist/PreferencesFacade.js +4 -9
- package/dist/PreferencesFacade.js.map +1 -1
- package/dist/PreferencesFacade.test.js +53 -55
- package/dist/PreferencesFacade.test.js.map +1 -1
- package/dist/cli/commands/attach.js +1 -1
- package/dist/cli/commands/attach.js.map +1 -1
- package/dist/cli/commands/build.d.ts +5 -1
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +43 -5
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/lib/manifest.d.ts +17 -5
- package/dist/cli/lib/manifest.d.ts.map +1 -1
- package/dist/cli/lib/manifest.js +125 -66
- package/dist/cli/lib/manifest.js.map +1 -1
- package/dist/{index.d.ts → contracts.d.ts} +25 -2
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +36 -0
- package/dist/contracts.js.map +1 -0
- package/dist/contracts.purity.test.d.ts +2 -0
- package/dist/contracts.purity.test.d.ts.map +1 -0
- package/dist/contracts.purity.test.js +42 -0
- package/dist/contracts.purity.test.js.map +1 -0
- package/dist/icons/AsyarIconElement.js +4 -9
- package/dist/icons/AsyarIconElement.js.map +1 -1
- package/dist/icons/AsyarIconElement.test.js +14 -16
- package/dist/icons/AsyarIconElement.test.js.map +1 -1
- package/dist/icons/IconRenderer.js +9 -15
- package/dist/icons/IconRenderer.js.map +1 -1
- package/dist/icons/IconRenderer.test.js +63 -65
- package/dist/icons/IconRenderer.test.js.map +1 -1
- package/dist/icons/iconData.js +2 -5
- package/dist/icons/iconData.js.map +1 -1
- package/dist/icons/index.js +3 -14
- package/dist/icons/index.js.map +1 -1
- package/dist/ipc/MessageBroker.d.ts.map +1 -1
- package/dist/ipc/MessageBroker.js +33 -6
- package/dist/ipc/MessageBroker.js.map +1 -1
- package/dist/ipc/MessageBroker.test.js +26 -28
- package/dist/ipc/MessageBroker.test.js.map +1 -1
- package/dist/ipc/devInspectorBridge.d.ts +57 -0
- package/dist/ipc/devInspectorBridge.d.ts.map +1 -0
- package/dist/ipc/devInspectorBridge.js +70 -0
- package/dist/ipc/devInspectorBridge.js.map +1 -0
- package/dist/ipc/devInspectorBridge.test.d.ts +2 -0
- package/dist/ipc/devInspectorBridge.test.d.ts.map +1 -0
- package/dist/ipc/devInspectorBridge.test.js +128 -0
- package/dist/ipc/devInspectorBridge.test.js.map +1 -0
- package/dist/ipc/namespaces.d.ts +1 -1
- package/dist/ipc/namespaces.d.ts.map +1 -1
- package/dist/ipc/namespaces.js +5 -7
- package/dist/ipc/namespaces.js.map +1 -1
- package/dist/ipc/namespaces.test.js +11 -12
- package/dist/ipc/namespaces.test.js.map +1 -1
- package/dist/lib/focusTracker.js +1 -4
- package/dist/lib/focusTracker.js.map +1 -1
- package/dist/lib/focusTracker.test.js +32 -57
- package/dist/lib/focusTracker.test.js.map +1 -1
- package/dist/lib/syncProviderBridge.js +1 -4
- package/dist/lib/syncProviderBridge.js.map +1 -1
- package/dist/lib/syncProviderBridge.test.js +60 -85
- package/dist/lib/syncProviderBridge.test.js.map +1 -1
- package/dist/lib/themeInjector.js +3 -8
- package/dist/lib/themeInjector.js.map +1 -1
- package/dist/lib/themeInjector.test.js +42 -44
- package/dist/lib/themeInjector.test.js.map +1 -1
- package/dist/search/SearchEngine.js +3 -10
- package/dist/search/SearchEngine.js.map +1 -1
- package/dist/search/SearchEngine.test.js +53 -55
- package/dist/search/SearchEngine.test.js.map +1 -1
- package/dist/search/index.js +2 -8
- package/dist/search/index.js.map +1 -1
- package/dist/search/textUtils.js +2 -6
- package/dist/search/textUtils.js.map +1 -1
- package/dist/search/textUtils.test.js +73 -75
- package/dist/search/textUtils.test.js.map +1 -1
- package/dist/search/types.js +1 -2
- package/dist/services/AIServiceProxy.js +2 -6
- package/dist/services/AIServiceProxy.js.map +1 -1
- package/dist/services/AIServiceProxy.test.js +69 -71
- package/dist/services/AIServiceProxy.test.js.map +1 -1
- package/dist/services/ActionServiceProxy.d.ts.map +1 -1
- package/dist/services/ActionServiceProxy.js +14 -13
- package/dist/services/ActionServiceProxy.js.map +1 -1
- package/dist/services/ActionServiceProxy.test.js +28 -23
- package/dist/services/ActionServiceProxy.test.js.map +1 -1
- package/dist/services/ApplicationService.js +2 -6
- package/dist/services/ApplicationService.js.map +1 -1
- package/dist/services/ApplicationService.test.js +108 -110
- package/dist/services/ApplicationService.test.js.map +1 -1
- package/dist/services/BaseServiceProxy.js +3 -7
- package/dist/services/BaseServiceProxy.js.map +1 -1
- package/dist/services/CacheServiceProxy.js +2 -6
- package/dist/services/CacheServiceProxy.js.map +1 -1
- package/dist/services/CacheServiceProxy.test.js +21 -23
- package/dist/services/CacheServiceProxy.test.js.map +1 -1
- package/dist/services/ClipboardHistoryServiceProxy.js +6 -10
- package/dist/services/ClipboardHistoryServiceProxy.js.map +1 -1
- package/dist/services/ClipboardHistoryServiceProxy.test.js +106 -108
- package/dist/services/ClipboardHistoryServiceProxy.test.js.map +1 -1
- package/dist/services/CommandServiceProxy.js +7 -11
- package/dist/services/CommandServiceProxy.js.map +1 -1
- package/dist/services/CommandServiceProxy.test.js +37 -39
- package/dist/services/CommandServiceProxy.test.js.map +1 -1
- package/dist/services/EntitlementServiceProxy.js +2 -6
- package/dist/services/EntitlementServiceProxy.js.map +1 -1
- package/dist/services/EntitlementServiceProxy.test.js +16 -18
- package/dist/services/EntitlementServiceProxy.test.js.map +1 -1
- package/dist/services/ExtensionManagerProxy.js +2 -6
- package/dist/services/ExtensionManagerProxy.js.map +1 -1
- package/dist/services/ExtensionManagerProxy.test.js +42 -44
- package/dist/services/ExtensionManagerProxy.test.js.map +1 -1
- package/dist/services/ExtensionRpc.d.ts +90 -0
- package/dist/services/ExtensionRpc.d.ts.map +1 -0
- package/dist/services/ExtensionRpc.js +277 -0
- package/dist/services/ExtensionRpc.js.map +1 -0
- package/dist/services/ExtensionRpc.test.d.ts +2 -0
- package/dist/services/ExtensionRpc.test.d.ts.map +1 -0
- package/dist/services/ExtensionRpc.test.js +259 -0
- package/dist/services/ExtensionRpc.test.js.map +1 -0
- package/dist/services/ExtensionStateProxy.d.ts +44 -0
- package/dist/services/ExtensionStateProxy.d.ts.map +1 -0
- package/dist/services/ExtensionStateProxy.js +115 -0
- package/dist/services/ExtensionStateProxy.js.map +1 -0
- package/dist/services/ExtensionStateProxy.test.d.ts +2 -0
- package/dist/services/ExtensionStateProxy.test.d.ts.map +1 -0
- package/dist/services/ExtensionStateProxy.test.js +158 -0
- package/dist/services/ExtensionStateProxy.test.js.map +1 -0
- package/dist/services/FeedbackServiceProxy.js +2 -6
- package/dist/services/FeedbackServiceProxy.js.map +1 -1
- package/dist/services/FeedbackServiceProxy.test.js +31 -33
- package/dist/services/FeedbackServiceProxy.test.js.map +1 -1
- package/dist/services/FileManagerServiceProxy.js +2 -6
- package/dist/services/FileManagerServiceProxy.js.map +1 -1
- package/dist/services/FileManagerServiceProxy.test.js +21 -23
- package/dist/services/FileManagerServiceProxy.test.js.map +1 -1
- package/dist/services/FileSystemWatcherService.d.ts +70 -0
- package/dist/services/FileSystemWatcherService.d.ts.map +1 -0
- package/dist/services/FileSystemWatcherService.js +83 -0
- package/dist/services/FileSystemWatcherService.js.map +1 -0
- package/dist/services/FileSystemWatcherService.test.d.ts +2 -0
- package/dist/services/FileSystemWatcherService.test.d.ts.map +1 -0
- package/dist/services/FileSystemWatcherService.test.js +159 -0
- package/dist/services/FileSystemWatcherService.test.js.map +1 -0
- package/dist/services/IAIService.js +1 -2
- package/dist/services/ICacheService.js +1 -2
- package/dist/services/IClipboardHistoryService.js +1 -2
- package/dist/services/ICommandService.js +1 -2
- package/dist/services/IEntitlementService.js +1 -2
- package/dist/services/IExtensionManager.js +1 -2
- package/dist/services/IFeedbackService.js +1 -2
- package/dist/services/IFileManagerService.js +1 -2
- package/dist/services/IInteropService.js +1 -5
- package/dist/services/IInteropService.js.map +1 -1
- package/dist/services/INotificationService.js +1 -2
- package/dist/services/IOAuthService.js +1 -2
- package/dist/services/IPowerService.js +1 -2
- package/dist/services/IPreferencesService.js +1 -2
- package/dist/services/ISelectionService.js +1 -2
- package/dist/services/ISettingsService.js +1 -2
- package/dist/services/IShellService.js +1 -2
- package/dist/services/IStatusBarService.js +1 -2
- package/dist/services/IStorageService.js +1 -2
- package/dist/services/ISystemEventsService.js +1 -2
- package/dist/services/ISystemEventsService.js.map +1 -1
- package/dist/services/ITimerService.js +1 -2
- package/dist/services/InteropServiceProxy.js +2 -6
- package/dist/services/InteropServiceProxy.js.map +1 -1
- package/dist/services/InteropServiceProxy.test.js +19 -21
- package/dist/services/InteropServiceProxy.test.js.map +1 -1
- package/dist/services/LogService.js +1 -2
- package/dist/services/LogServiceProxy.js +2 -6
- package/dist/services/LogServiceProxy.js.map +1 -1
- package/dist/services/LogServiceProxy.test.js +43 -45
- package/dist/services/LogServiceProxy.test.js.map +1 -1
- package/dist/services/NetworkServiceProxy.js +2 -6
- package/dist/services/NetworkServiceProxy.js.map +1 -1
- package/dist/services/NetworkServiceProxy.test.js +20 -22
- package/dist/services/NetworkServiceProxy.test.js.map +1 -1
- package/dist/services/NotificationServiceProxy.js +2 -6
- package/dist/services/NotificationServiceProxy.js.map +1 -1
- package/dist/services/NotificationServiceProxy.test.js +39 -41
- package/dist/services/NotificationServiceProxy.test.js.map +1 -1
- package/dist/services/OAuthServiceProxy.js +2 -6
- package/dist/services/OAuthServiceProxy.js.map +1 -1
- package/dist/services/OAuthServiceProxy.test.js +42 -44
- package/dist/services/OAuthServiceProxy.test.js.map +1 -1
- package/dist/services/PowerServiceProxy.js +2 -6
- package/dist/services/PowerServiceProxy.js.map +1 -1
- package/dist/services/PowerServiceProxy.test.js +24 -26
- package/dist/services/PowerServiceProxy.test.js.map +1 -1
- package/dist/services/PreferencesServiceProxy.js +2 -6
- package/dist/services/PreferencesServiceProxy.js.map +1 -1
- package/dist/services/PreferencesServiceProxy.test.js +22 -24
- package/dist/services/PreferencesServiceProxy.test.js.map +1 -1
- package/dist/services/SelectionServiceProxy.js +2 -6
- package/dist/services/SelectionServiceProxy.js.map +1 -1
- package/dist/services/SelectionServiceProxy.test.js +20 -22
- package/dist/services/SelectionServiceProxy.test.js.map +1 -1
- package/dist/services/SettingsServiceProxy.js +2 -6
- package/dist/services/SettingsServiceProxy.js.map +1 -1
- package/dist/services/SettingsServiceProxy.test.js +18 -20
- package/dist/services/SettingsServiceProxy.test.js.map +1 -1
- package/dist/services/ShellServiceProxy.js +2 -6
- package/dist/services/ShellServiceProxy.js.map +1 -1
- package/dist/services/ShellServiceProxy.test.js +92 -94
- package/dist/services/ShellServiceProxy.test.js.map +1 -1
- package/dist/services/StatusBarServiceProxy.js +9 -13
- package/dist/services/StatusBarServiceProxy.js.map +1 -1
- package/dist/services/StatusBarServiceProxy.test.js +68 -70
- package/dist/services/StatusBarServiceProxy.test.js.map +1 -1
- package/dist/services/StorageServiceProxy.js +2 -6
- package/dist/services/StorageServiceProxy.js.map +1 -1
- package/dist/services/StorageServiceProxy.test.js +31 -33
- package/dist/services/StorageServiceProxy.test.js.map +1 -1
- package/dist/services/SystemEventsServiceProxy.js +2 -6
- package/dist/services/SystemEventsServiceProxy.js.map +1 -1
- package/dist/services/SystemEventsServiceProxy.test.js +50 -52
- package/dist/services/SystemEventsServiceProxy.test.js.map +1 -1
- package/dist/services/TimerServiceProxy.js +2 -6
- package/dist/services/TimerServiceProxy.js.map +1 -1
- package/dist/services/TimerServiceProxy.test.js +33 -35
- package/dist/services/TimerServiceProxy.test.js.map +1 -1
- package/dist/services/WindowManagementService.js +2 -6
- package/dist/services/WindowManagementService.js.map +1 -1
- package/dist/services/WindowManagementService.test.js +23 -25
- package/dist/services/WindowManagementService.test.js.map +1 -1
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +36 -74
- package/dist/services/index.js.map +1 -1
- package/dist/services/statusBarValidation.js +7 -14
- package/dist/services/statusBarValidation.js.map +1 -1
- package/dist/types/ActionType.js +3 -6
- package/dist/types/ActionType.js.map +1 -1
- package/dist/types/ApplicationType.js +1 -2
- package/dist/types/ClipboardType.js +2 -5
- package/dist/types/ClipboardType.js.map +1 -1
- package/dist/types/CommandType.js +1 -2
- package/dist/types/ExtensionType.d.ts +40 -5
- package/dist/types/ExtensionType.d.ts.map +1 -1
- package/dist/types/ExtensionType.js +1 -2
- package/dist/types/NetworkType.js +1 -2
- package/dist/types/NotificationType.js +1 -2
- package/dist/types/SyncType.js +1 -2
- package/dist/types/index.js +2 -18
- package/dist/types/index.js.map +1 -1
- package/dist/view.d.ts +12 -0
- package/dist/view.d.ts.map +1 -0
- package/dist/view.js +19 -0
- package/dist/view.js.map +1 -0
- package/dist/view.test.d.ts +2 -0
- package/dist/view.test.d.ts.map +1 -0
- package/dist/view.test.js +114 -0
- package/dist/view.test.js.map +1 -0
- package/dist/worker.bundle-size.test.d.ts +2 -0
- package/dist/worker.bundle-size.test.d.ts.map +1 -0
- package/dist/worker.bundle-size.test.js +96 -0
- package/dist/worker.bundle-size.test.js.map +1 -0
- package/dist/worker.d.ts +37 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +122 -0
- package/dist/worker.js.map +1 -0
- package/dist/worker.test.d.ts +2 -0
- package/dist/worker.test.d.ts.map +1 -0
- package/dist/worker.test.js +136 -0
- package/dist/worker.test.js.map +1 -0
- package/package.json +12 -4
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -45
- package/dist/index.js.map +0 -1
package/dist/ExtensionContext.js
CHANGED
|
@@ -1,218 +1,97 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
1
|
+
import { LogServiceProxy, NotificationServiceProxy, ClipboardHistoryServiceProxy, ExtensionManagerProxy, CommandServiceProxy, ActionServiceProxy, NetworkServiceProxy, SettingsServiceProxy, StatusBarServiceProxy, EntitlementServiceProxy, StorageServiceProxy, FeedbackServiceProxy, SelectionServiceProxy, ShellServiceProxy, CacheServiceProxy, ApplicationServiceProxy, } from "./services";
|
|
2
|
+
import { AIServiceProxy } from './services/AIServiceProxy';
|
|
3
|
+
import { OAuthServiceProxy } from './services/OAuthServiceProxy';
|
|
4
|
+
import { FileManagerServiceProxy } from './services/FileManagerServiceProxy';
|
|
5
|
+
import { InteropServiceProxy } from './services/InteropServiceProxy';
|
|
6
|
+
import { WindowManagementServiceProxy } from './services/WindowManagementService';
|
|
7
|
+
import { PowerServiceProxy } from './services/PowerServiceProxy';
|
|
8
|
+
import { SystemEventsServiceProxy } from './services/SystemEventsServiceProxy';
|
|
9
|
+
import { TimerServiceProxy } from './services/TimerServiceProxy';
|
|
10
|
+
import { FileSystemWatcherServiceProxy } from './services/FileSystemWatcherService';
|
|
11
|
+
import { ExtensionStateProxy } from './services/ExtensionStateProxy';
|
|
12
|
+
import { extensionRpc } from './services/ExtensionRpc';
|
|
13
|
+
export { PreferencesFacade } from './PreferencesFacade';
|
|
14
|
+
import { setupFocusTracking } from './lib/focusTracker';
|
|
15
|
+
import { setupThemeInjection } from './lib/themeInjector';
|
|
16
|
+
export { injectThemeVariables, injectFontFaceCSS } from './lib/themeInjector';
|
|
17
|
+
import { ExtensionContextCore } from './ExtensionContextCore';
|
|
18
|
+
export { ExtensionContextCore } from './ExtensionContextCore';
|
|
19
|
+
function buildFullProxyBag() {
|
|
20
|
+
return {
|
|
21
|
+
log: new LogServiceProxy(),
|
|
22
|
+
notifications: new NotificationServiceProxy(),
|
|
23
|
+
clipboard: new ClipboardHistoryServiceProxy(),
|
|
24
|
+
extensions: new ExtensionManagerProxy(),
|
|
25
|
+
commands: new CommandServiceProxy(),
|
|
26
|
+
actions: new ActionServiceProxy(),
|
|
27
|
+
network: new NetworkServiceProxy(),
|
|
28
|
+
settings: new SettingsServiceProxy(),
|
|
29
|
+
statusBar: new StatusBarServiceProxy(),
|
|
30
|
+
entitlements: new EntitlementServiceProxy(),
|
|
31
|
+
storage: new StorageServiceProxy(),
|
|
32
|
+
feedback: new FeedbackServiceProxy(),
|
|
33
|
+
selection: new SelectionServiceProxy(),
|
|
34
|
+
ai: new AIServiceProxy(),
|
|
35
|
+
oauth: new OAuthServiceProxy(),
|
|
36
|
+
shell: new ShellServiceProxy(),
|
|
37
|
+
fs: new FileManagerServiceProxy(),
|
|
38
|
+
interop: new InteropServiceProxy(),
|
|
39
|
+
cache: new CacheServiceProxy(),
|
|
40
|
+
application: new ApplicationServiceProxy(),
|
|
41
|
+
window: new WindowManagementServiceProxy(),
|
|
42
|
+
power: new PowerServiceProxy(),
|
|
43
|
+
systemEvents: new SystemEventsServiceProxy(),
|
|
44
|
+
timers: new TimerServiceProxy(),
|
|
45
|
+
fsWatcher: new FileSystemWatcherServiceProxy(),
|
|
46
|
+
state: new ExtensionStateProxy(),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Full-surface ExtensionContext. Backs:
|
|
51
|
+
* - Tier 1 launcher built-in features (type-only reference).
|
|
52
|
+
* - `asyar-sdk/view` entry point (UI-capable extensions).
|
|
53
|
+
*
|
|
54
|
+
* For worker-context extensions, see `asyar-sdk/worker` — it exports a
|
|
55
|
+
* narrower ExtensionContext without DOM-dependent proxies.
|
|
56
|
+
*/
|
|
57
|
+
export class ExtensionContext extends ExtensionContextCore {
|
|
58
|
+
constructor() {
|
|
59
|
+
super({ role: 'view', proxies: buildFullProxyBag() });
|
|
60
|
+
setupFocusTracking();
|
|
61
|
+
setupThemeInjection();
|
|
62
|
+
// View-side RPC plumbing: install the reply-push listener once per
|
|
63
|
+
// ExtensionContext construction, and wire a `pagehide` handler that
|
|
64
|
+
// drops every pending reply so the next mount sees no zombie state.
|
|
65
|
+
// The view-side ExtensionStateProxy's pagehide auto-unsubscribe is
|
|
66
|
+
// installed alongside so every active subscription is torn down in
|
|
67
|
+
// the same cleanup pass.
|
|
68
|
+
extensionRpc.installViewMessageListener();
|
|
69
|
+
extensionRpc.installViewAutoCleanup();
|
|
70
|
+
const stateProxy = this.proxies.state;
|
|
71
|
+
stateProxy === null || stateProxy === void 0 ? void 0 : stateProxy.installViewAutoUnsubscribe();
|
|
47
72
|
}
|
|
48
73
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* Typical use: an extension that caches a preference value at
|
|
55
|
-
* `initialize()` time (e.g. to feed a timer engine's internal state)
|
|
56
|
-
* uses this to recompute when the user edits the setting.
|
|
74
|
+
* View-side RPC entry. Sends a request into this extension's worker and
|
|
75
|
+
* awaits the worker handler's reply. Default 5s timeout, overridable via
|
|
76
|
+
* `opts.timeoutMs`. See `ExtensionRpc.request` for the AbortSignal +
|
|
77
|
+
* stale-reply contract.
|
|
57
78
|
*/
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return () => {
|
|
61
|
-
this.preferenceChangeListeners = this.preferenceChangeListeners.filter((l) => l !== callback);
|
|
62
|
-
};
|
|
79
|
+
request(id, payload, opts) {
|
|
80
|
+
return extensionRpc.request(id, payload, opts);
|
|
63
81
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.preferences = new PreferencesFacade_1.PreferencesFacade();
|
|
67
|
-
/**
|
|
68
|
-
* Listeners notified *after* `setPreferences` installs a new frozen
|
|
69
|
-
* snapshot. Callbacks take no arguments and must re-read fresh values
|
|
70
|
-
* from `context.preferences.values` — the snapshot is already in place
|
|
71
|
-
* when they fire. This is a read-only notification, not a live getter:
|
|
72
|
-
* extensions that cache preference values at boot subscribe here to
|
|
73
|
-
* recompute when the user edits their settings.
|
|
74
|
-
*/
|
|
75
|
-
this.preferenceChangeListeners = [];
|
|
76
|
-
// The local registry is now strictly for proxies. Keys are canonical
|
|
77
|
-
// Namespace values — the same identifiers used on the wire — so a typo or
|
|
78
|
-
// class-name-shaped key fails to compile.
|
|
79
|
-
this.proxies = {
|
|
80
|
-
log: new services_1.LogServiceProxy(),
|
|
81
|
-
notifications: new services_1.NotificationServiceProxy(),
|
|
82
|
-
clipboard: new services_1.ClipboardHistoryServiceProxy(),
|
|
83
|
-
extensions: new services_1.ExtensionManagerProxy(),
|
|
84
|
-
commands: new services_1.CommandServiceProxy(),
|
|
85
|
-
actions: new services_1.ActionServiceProxy(),
|
|
86
|
-
network: new services_1.NetworkServiceProxy(),
|
|
87
|
-
settings: new services_1.SettingsServiceProxy(),
|
|
88
|
-
statusBar: new services_1.StatusBarServiceProxy(),
|
|
89
|
-
entitlements: new services_1.EntitlementServiceProxy(),
|
|
90
|
-
storage: new services_1.StorageServiceProxy(),
|
|
91
|
-
feedback: new services_1.FeedbackServiceProxy(),
|
|
92
|
-
selection: new services_1.SelectionServiceProxy(),
|
|
93
|
-
ai: new AIServiceProxy_1.AIServiceProxy(),
|
|
94
|
-
oauth: new OAuthServiceProxy_1.OAuthServiceProxy(),
|
|
95
|
-
shell: new services_1.ShellServiceProxy(),
|
|
96
|
-
fs: new FileManagerServiceProxy_1.FileManagerServiceProxy(),
|
|
97
|
-
interop: new InteropServiceProxy_1.InteropServiceProxy(),
|
|
98
|
-
cache: new services_1.CacheServiceProxy(),
|
|
99
|
-
application: new services_1.ApplicationServiceProxy(),
|
|
100
|
-
window: new WindowManagementService_1.WindowManagementServiceProxy(),
|
|
101
|
-
power: new PowerServiceProxy_1.PowerServiceProxy(),
|
|
102
|
-
systemEvents: new SystemEventsServiceProxy_1.SystemEventsServiceProxy(),
|
|
103
|
-
timers: new TimerServiceProxy_1.TimerServiceProxy(),
|
|
104
|
-
};
|
|
105
|
-
(0, focusTracker_1.setupFocusTracking)();
|
|
106
|
-
(0, themeInjector_1.setupThemeInjection)();
|
|
82
|
+
notifyRpcIfAvailable(id) {
|
|
83
|
+
extensionRpc.setExtensionId(id);
|
|
107
84
|
}
|
|
108
|
-
|
|
109
|
-
getService(namespace) {
|
|
110
|
-
const service = this.proxies[namespace];
|
|
111
|
-
if (!service) {
|
|
112
|
-
throw new Error(`Service "${namespace}" not registered`);
|
|
113
|
-
}
|
|
114
|
-
return service;
|
|
115
|
-
}
|
|
116
|
-
setExtensionId(id) {
|
|
117
|
-
this.extensionId = id;
|
|
118
|
-
// Inject into proxies if they support it
|
|
119
|
-
for (const key of Object.keys(this.proxies)) {
|
|
120
|
-
const svc = this.proxies[key];
|
|
121
|
-
if (svc && typeof svc.setExtensionId === 'function') {
|
|
122
|
-
svc.setExtensionId(id);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
// The preferences facade composes its own proxy privately since it's
|
|
126
|
-
// no longer in the proxies bag; push the id into it explicitly.
|
|
127
|
-
this.preferences._setExtensionId(id);
|
|
128
|
-
// The ExtensionBridge singleton has its own internal LogServiceProxy that
|
|
129
|
-
// is constructed before any extension context exists, so it never goes
|
|
130
|
-
// through the proxies-bag patching above. Push the extensionId to it now
|
|
131
|
-
// so its `Registered action: ...` and similar debug logs don't get
|
|
132
|
-
// rejected by the host IPC router for missing extensionId.
|
|
133
|
-
//
|
|
134
|
-
// We also self-register this context as the active context for this
|
|
135
|
-
// extension id. Tier 2 iframes that bootstrap by creating their own
|
|
136
|
-
// `ExtensionContext` (rather than going through
|
|
137
|
-
// `bridge.initializeExtensions()`) otherwise never appear in the
|
|
138
|
-
// bridge's `activeContexts` map, and `asyar:event:preferences:set-all`
|
|
139
|
-
// can't find the live context to call `setPreferences` on.
|
|
85
|
+
notifyBridgeIfAvailable(id) {
|
|
140
86
|
try {
|
|
141
|
-
|
|
142
|
-
|
|
87
|
+
extensionBridge.setExtensionId(id);
|
|
88
|
+
extensionBridge.registerActiveContext(id, this);
|
|
143
89
|
}
|
|
144
90
|
catch (_a) {
|
|
145
|
-
//
|
|
146
|
-
// if for some reason it's not yet available, silently skip — the failure
|
|
147
|
-
// mode is just the pre-existing log spam, not a hard error.
|
|
148
|
-
}
|
|
149
|
-
// Notify host the iframe is ready for mailbox drain. Host readiness
|
|
150
|
-
// listener calls iframe_ready_ack on receipt.
|
|
151
|
-
try {
|
|
152
|
-
if (typeof window !== 'undefined' &&
|
|
153
|
-
window.parent &&
|
|
154
|
-
window.parent !== window &&
|
|
155
|
-
typeof window.parent.postMessage === 'function') {
|
|
156
|
-
window.parent.postMessage({ type: 'asyar:extension:loaded', extensionId: id }, '*');
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
catch (_b) {
|
|
160
|
-
// best-effort — host will time out and strike if we can't signal.
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
registerAction(action) {
|
|
164
|
-
if (!this.extensionId) {
|
|
165
|
-
console.error("Cannot register action: Extension ID not set");
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
const actionService = this.getService('actions');
|
|
169
|
-
actionService.registerAction(action);
|
|
170
|
-
}
|
|
171
|
-
unregisterAction(actionId) {
|
|
172
|
-
const actionService = this.getService('actions');
|
|
173
|
-
actionService.unregisterAction(actionId);
|
|
174
|
-
}
|
|
175
|
-
registerCommand(commandId, handler) {
|
|
176
|
-
if (!this.extensionId) {
|
|
177
|
-
console.error("Cannot register command: Extension ID not set");
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
const fullCommandId = `${this.extensionId}.${commandId}`;
|
|
181
|
-
const commandService = this.getService('commands');
|
|
182
|
-
commandService.registerCommand(fullCommandId, handler, this.extensionId);
|
|
183
|
-
}
|
|
184
|
-
unregisterCommand(commandId) {
|
|
185
|
-
const fullCommandId = `${this.extensionId}.${commandId}`;
|
|
186
|
-
const commandService = this.getService('commands');
|
|
187
|
-
commandService.unregisterCommand(fullCommandId);
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Build an `asyar://extensions/{extensionId}/{commandId}?args` deep link URL
|
|
191
|
-
* for a command owned by this extension. Pure string formatting — no IPC.
|
|
192
|
-
*
|
|
193
|
-
* Extensions can embed the returned URL in notifications, clipboard output,
|
|
194
|
-
* generated documents, or pass it to other apps.
|
|
195
|
-
*/
|
|
196
|
-
createDeeplink(commandId, args) {
|
|
197
|
-
if (!this.extensionId) {
|
|
198
|
-
throw new Error('Cannot create deeplink: Extension ID not set');
|
|
199
|
-
}
|
|
200
|
-
let url = `asyar://extensions/${encodeURIComponent(this.extensionId)}/${encodeURIComponent(commandId)}`;
|
|
201
|
-
if (args && Object.keys(args).length > 0) {
|
|
202
|
-
const params = new URLSearchParams(args).toString();
|
|
203
|
-
url += `?${params}`;
|
|
204
|
-
}
|
|
205
|
-
return url;
|
|
206
|
-
}
|
|
207
|
-
registerSyncProvider(provider) {
|
|
208
|
-
if (!this.extensionId) {
|
|
209
|
-
console.error("Cannot register sync provider: Extension ID not set");
|
|
210
|
-
return;
|
|
91
|
+
// bridge module not yet available (circular import startup); skip.
|
|
211
92
|
}
|
|
212
|
-
(0, syncProviderBridge_1.registerSyncProvider)(this.extensionId, provider);
|
|
213
93
|
}
|
|
214
94
|
}
|
|
215
|
-
exports.ExtensionContext = ExtensionContext;
|
|
216
95
|
// Import at the end to avoid circular dependencies
|
|
217
|
-
|
|
96
|
+
import { extensionBridge } from "./ExtensionBridge";
|
|
218
97
|
//# sourceMappingURL=ExtensionContext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExtensionContext.js","sourceRoot":"","sources":["../src/ExtensionContext.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExtensionContext.js","sourceRoot":"","sources":["../src/ExtensionContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,129 +1,154 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
3
10
|
/** @vitest-environment jsdom */
|
|
4
|
-
|
|
5
|
-
const { mockInvoke } =
|
|
6
|
-
mockInvoke:
|
|
11
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
12
|
+
const { mockInvoke } = vi.hoisted(() => ({
|
|
13
|
+
mockInvoke: vi.fn().mockResolvedValue(undefined),
|
|
7
14
|
}));
|
|
8
|
-
|
|
15
|
+
vi.mock('./ipc/MessageBroker', () => ({
|
|
9
16
|
messageBroker: {
|
|
10
17
|
invoke: mockInvoke,
|
|
11
|
-
on:
|
|
12
|
-
off:
|
|
18
|
+
on: vi.fn(),
|
|
19
|
+
off: vi.fn(),
|
|
13
20
|
},
|
|
14
21
|
}));
|
|
15
|
-
|
|
16
|
-
|
|
22
|
+
import { ExtensionContext } from './ExtensionContext';
|
|
23
|
+
beforeEach(() => {
|
|
17
24
|
mockInvoke.mockReset();
|
|
18
25
|
mockInvoke.mockResolvedValue(undefined);
|
|
19
26
|
});
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const ctx = new
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
describe('ExtensionContext preferences snapshot', () => {
|
|
28
|
+
it('starts with an empty frozen snapshot at .values', () => {
|
|
29
|
+
const ctx = new ExtensionContext();
|
|
30
|
+
expect(ctx.preferences.values.commands).toBeDefined();
|
|
31
|
+
expect(Object.isFrozen(ctx.preferences.values)).toBe(true);
|
|
32
|
+
expect(Object.isFrozen(ctx.preferences.values.commands)).toBe(true);
|
|
26
33
|
});
|
|
27
|
-
|
|
28
|
-
const ctx = new
|
|
34
|
+
it('setPreferences installs a frozen snapshot at every level of .values', () => {
|
|
35
|
+
const ctx = new ExtensionContext();
|
|
29
36
|
ctx.setPreferences({
|
|
30
37
|
extension: { apiKey: 'abc', units: 'metric' },
|
|
31
38
|
commands: { forecast: { days: 5 } },
|
|
32
39
|
});
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
expect(ctx.preferences.values.apiKey).toBe('abc');
|
|
41
|
+
expect(ctx.preferences.values.units).toBe('metric');
|
|
42
|
+
expect(ctx.preferences.values.commands.forecast.days).toBe(5);
|
|
43
|
+
expect(Object.isFrozen(ctx.preferences.values)).toBe(true);
|
|
44
|
+
expect(Object.isFrozen(ctx.preferences.values.commands)).toBe(true);
|
|
45
|
+
expect(Object.isFrozen(ctx.preferences.values.commands.forecast)).toBe(true);
|
|
39
46
|
});
|
|
40
|
-
|
|
47
|
+
it('direct mutation of the snapshot is rejected', () => {
|
|
41
48
|
'use strict';
|
|
42
|
-
const ctx = new
|
|
49
|
+
const ctx = new ExtensionContext();
|
|
43
50
|
ctx.setPreferences({ extension: { x: 1 }, commands: {} });
|
|
44
|
-
|
|
51
|
+
expect(() => {
|
|
45
52
|
ctx.preferences.values.x = 999;
|
|
46
53
|
}).toThrow();
|
|
47
54
|
});
|
|
48
|
-
|
|
49
|
-
const ctx = new
|
|
55
|
+
it('setPreferences tolerates an absent commands field', () => {
|
|
56
|
+
const ctx = new ExtensionContext();
|
|
50
57
|
ctx.setPreferences({ extension: { a: 1 }, commands: undefined });
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
expect(ctx.preferences.values.a).toBe(1);
|
|
59
|
+
expect(ctx.preferences.values.commands).toEqual({});
|
|
53
60
|
});
|
|
54
61
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const ctx = new
|
|
58
|
-
const listener =
|
|
62
|
+
describe('ExtensionContext onPreferencesChanged', () => {
|
|
63
|
+
it('fires registered listeners after setPreferences', () => {
|
|
64
|
+
const ctx = new ExtensionContext();
|
|
65
|
+
const listener = vi.fn();
|
|
59
66
|
ctx.onPreferencesChanged(listener);
|
|
60
67
|
ctx.setPreferences({ extension: { x: 1 }, commands: {} });
|
|
61
|
-
|
|
68
|
+
expect(listener).toHaveBeenCalledTimes(1);
|
|
62
69
|
ctx.setPreferences({ extension: { x: 2 }, commands: {} });
|
|
63
|
-
|
|
70
|
+
expect(listener).toHaveBeenCalledTimes(2);
|
|
64
71
|
});
|
|
65
|
-
|
|
66
|
-
const ctx = new
|
|
72
|
+
it('listener sees the new snapshot at .values when it fires', () => {
|
|
73
|
+
const ctx = new ExtensionContext();
|
|
67
74
|
let observedValue;
|
|
68
75
|
ctx.onPreferencesChanged(() => {
|
|
69
76
|
observedValue = ctx.preferences.values.focusMinutes;
|
|
70
77
|
});
|
|
71
78
|
ctx.setPreferences({ extension: { focusMinutes: 25 }, commands: {} });
|
|
72
|
-
|
|
79
|
+
expect(observedValue).toBe(25);
|
|
73
80
|
ctx.setPreferences({ extension: { focusMinutes: 50 }, commands: {} });
|
|
74
|
-
|
|
81
|
+
expect(observedValue).toBe(50);
|
|
75
82
|
});
|
|
76
|
-
|
|
77
|
-
const ctx = new
|
|
78
|
-
const listener =
|
|
83
|
+
it('unsubscribe function removes the listener', () => {
|
|
84
|
+
const ctx = new ExtensionContext();
|
|
85
|
+
const listener = vi.fn();
|
|
79
86
|
const unsubscribe = ctx.onPreferencesChanged(listener);
|
|
80
87
|
ctx.setPreferences({ extension: {}, commands: {} });
|
|
81
|
-
|
|
88
|
+
expect(listener).toHaveBeenCalledTimes(1);
|
|
82
89
|
unsubscribe();
|
|
83
90
|
ctx.setPreferences({ extension: {}, commands: {} });
|
|
84
|
-
|
|
91
|
+
expect(listener).toHaveBeenCalledTimes(1);
|
|
85
92
|
});
|
|
86
|
-
|
|
87
|
-
const ctx = new
|
|
88
|
-
const good1 =
|
|
89
|
-
const bad =
|
|
93
|
+
it('one listener throwing does not prevent others from running', () => {
|
|
94
|
+
const ctx = new ExtensionContext();
|
|
95
|
+
const good1 = vi.fn();
|
|
96
|
+
const bad = vi.fn(() => {
|
|
90
97
|
throw new Error('boom');
|
|
91
98
|
});
|
|
92
|
-
const good2 =
|
|
93
|
-
const errSpy =
|
|
99
|
+
const good2 = vi.fn();
|
|
100
|
+
const errSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
94
101
|
ctx.onPreferencesChanged(good1);
|
|
95
102
|
ctx.onPreferencesChanged(bad);
|
|
96
103
|
ctx.onPreferencesChanged(good2);
|
|
97
104
|
ctx.setPreferences({ extension: {}, commands: {} });
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
105
|
+
expect(good1).toHaveBeenCalled();
|
|
106
|
+
expect(bad).toHaveBeenCalled();
|
|
107
|
+
expect(good2).toHaveBeenCalled();
|
|
108
|
+
expect(errSpy).toHaveBeenCalled();
|
|
102
109
|
errSpy.mockRestore();
|
|
103
110
|
});
|
|
104
|
-
|
|
105
|
-
const ctx = new
|
|
106
|
-
const listener =
|
|
111
|
+
it('returns a stable unsubscribe even when called multiple times', () => {
|
|
112
|
+
const ctx = new ExtensionContext();
|
|
113
|
+
const listener = vi.fn();
|
|
107
114
|
const unsubscribe = ctx.onPreferencesChanged(listener);
|
|
108
115
|
unsubscribe();
|
|
109
116
|
unsubscribe();
|
|
110
117
|
ctx.setPreferences({ extension: {}, commands: {} });
|
|
111
|
-
|
|
118
|
+
expect(listener).not.toHaveBeenCalled();
|
|
112
119
|
});
|
|
113
120
|
});
|
|
114
|
-
|
|
121
|
+
describe('ExtensionContext.setExtensionId', () => {
|
|
115
122
|
let parentPostMessage;
|
|
116
|
-
|
|
117
|
-
parentPostMessage =
|
|
123
|
+
beforeEach(() => {
|
|
124
|
+
parentPostMessage = vi.fn();
|
|
118
125
|
Object.defineProperty(window, 'parent', {
|
|
119
126
|
value: { postMessage: parentPostMessage },
|
|
120
127
|
configurable: true,
|
|
121
128
|
});
|
|
122
129
|
});
|
|
123
|
-
|
|
124
|
-
const ctx = new
|
|
130
|
+
it('emits asyar:extension:loaded to window.parent with extensionId + role', () => {
|
|
131
|
+
const ctx = new ExtensionContext();
|
|
125
132
|
ctx.setExtensionId('ext.test');
|
|
126
|
-
|
|
133
|
+
expect(parentPostMessage).toHaveBeenCalledWith(expect.objectContaining({
|
|
134
|
+
type: 'asyar:extension:loaded',
|
|
135
|
+
extensionId: 'ext.test',
|
|
136
|
+
role: expect.stringMatching(/^(worker|view)$/),
|
|
137
|
+
}), '*');
|
|
127
138
|
});
|
|
139
|
+
it('patches extensionRpc singleton via notifyRpcIfAvailable hook (regression: sdk-playground rpc rejections due to missing extensionId)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
140
|
+
// extensionRpc is a module-level singleton outside the proxies bag,
|
|
141
|
+
// so the proxy-bag iteration in ExtensionContextCore.setExtensionId
|
|
142
|
+
// never visits it. Before the fix, its broker stayed unpatched and
|
|
143
|
+
// every context.request(...) sent state:rpcRequest with no
|
|
144
|
+
// extensionId — rejected by the launcher IPC router. The view-side
|
|
145
|
+
// ExtensionContext now overrides notifyRpcIfAvailable to push the
|
|
146
|
+
// id through extensionRpc.setExtensionId.
|
|
147
|
+
const { extensionRpc } = yield import('./services/ExtensionRpc');
|
|
148
|
+
const rpcSetIdSpy = vi.spyOn(extensionRpc, 'setExtensionId');
|
|
149
|
+
const ctx = new ExtensionContext();
|
|
150
|
+
ctx.setExtensionId('ext.rpc-check');
|
|
151
|
+
expect(rpcSetIdSpy).toHaveBeenCalledWith('ext.rpc-check');
|
|
152
|
+
}));
|
|
128
153
|
});
|
|
129
154
|
//# sourceMappingURL=ExtensionContext.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExtensionContext.test.js","sourceRoot":"","sources":["../src/ExtensionContext.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExtensionContext.test.js","sourceRoot":"","sources":["../src/ExtensionContext.test.ts"],"names":[],"mappings":"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"}
|