Skip to content

fix(safari)!: align alarms and action contracts across browsers - #42

Closed
atldays wants to merge 6 commits into
codex/scripting-result-typesfrom
codex/safari-api-compatibility
Closed

atldays wants to merge 6 commits into
codex/scripting-result-typesfrom
codex/safari-api-compatibility

Conversation

@atldays

@atldays atldays commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Addresses #40. Stacked on the separate scripting type compatibility fix (#41); that prerequisite keeps fresh consumer installations buildable.

WebKit's alarms.create rejects the callback previously supplied by the wrapper, missing alarms/current tabs can return null, and action.isEnabled expects a details object. Adapt the supported calls, keep callback handling for other methods, and make missing native methods identifiable by API name.

  • Keep Promise<boolean> for alarm removal. clearAlarm(name) pre-reads only WebKit and prefers a native boolean. Unexpected non-boolean results elsewhere reject.
  • clearAllAlarm() reads getAll before deletion in every browser and reports whether that collection was nonempty, ignoring inconsistent native results. Both removal observations are non-atomic.
  • Export ApiMethodName<T> and support optional native method names in all 32 availability helpers. Update every documentation signature and packed consumer type checks.
  • Normalize getAlarm/getCurrentTab absence to undefined and removeCookie absence to null. Preserve native cookie details and callback errors.
  • Select action/browserAction consistently in diagnostics. Keep regression tests beside the owning API methods.
  • Add disposable native WebKit and Chromium/Firefox compatibility suites. Saved observations and hosted macOS CI are in the separate follow-up PR test(webkit): record API observations and add a macOS pilot #43.

Breaking changes, recorded on their owning commits:

  • An empty Chromium clearAllAlarm now returns false instead of the native true. The public boolean type stays unchanged.
  • removeCookie returns CookieDetails | null; consumers must handle null.
  • Unsupported getBrowserInfo rejects its Promise instead of throwing synchronously. Guarded missing methods now use API-named Error objects instead of native TypeError messages.
Verification Evidence
Runtime tested System WebKit 22625.2.8.11.9 on macOS 27.2, Chromium 153.0.8010.12, Firefox 159.0. Alarm creation/get/getAll, one-shot/repeating schedules, second conditional creation preserving scheduledTime, strict true/false deletion including empty clearAll, action state/badge callbacks, absent current tab/cookie results, error propagation.
Absent in exposed WebKit namespaces action.getBadgeTextColor/getUserSettings/setBadgeTextColor; cookies.getPartitionKey; tabs.discard/highlight/group/ungroup/getZoomSettings/setZoomSettings; permissions.addHostAccessRequest/removeHostAccessRequest; runtime.getBrowserInfo/getContexts/getPackageDirectoryEntry/requestUpdateCheck/restart/restartAfterDelay; declarativeNetRequest.getAvailableStaticRuleCount/getDisabledRuleIds/testMatchOutcome/updateStaticRules; i18n.detectLanguage; extension.setUpdateUrlData; webRequest.handlerBehaviorChanged. This is fixture/build/permission-specific exposure, not universal Safari support data.
Context-limited absence runtime.connectNative was not exposed without requesting nativeMessaging. Legacy tabs.executeScript/insertCSS/removeCSS are absent in MV3, where the wrappers select scripting. Withheld namespaces are not classified as unsupported browser features.
Source-only / unit Typed callable availability, unsupported-method guards, old synchronous/new Promise WebKit creation paths and missing-result normalization. Presence alone establishes neither valid arguments nor successful execution.
Remaining gaps Every wrapper's full successful/error behavior and option/result fields, delayed alarm firing/events, Safari application UI and gestures, popup presentation, iOS, optional host/build features and other versions.

Validation: 139 Jest suites / 3267 tests; lint, generated-source check, source/test/browser typechecks, build and tree shaking, packed ESM/CJS consumer checks. Each logical intermediate commit was independently built/typechecked and relevant tests run. Both the base WebKit host and the report-enhanced host passed all five scenarios.

See docs/safari.md for the dated verification snapshot and migration details. No release or changelog generation is included.

The follow-up WebKit pilot also passed all five scenarios on macOS 15.8.2 / WebKit 20621.3.11.11.3 and macOS 26.7.2 / WebKit 21624.5.1.11.3; its downloaded artifacts record actual granted permissions including webRequest.

Stack order: #41 → this PR → #43. Existing core CI filters PR bases to develop/feature branches, so it will run for this PR after the prerequisite lands and the base is retargeted to develop. The local package checks and native runtime results above are already complete.

Accept optional native method names in every availability helper and export
ApiMethodName for consumer wrappers. Keep no-argument namespace checks.
Keep boolean results for named deletion and derive legacy WebKit results from
an existence check. Read the collection before clearAll in every browser and
ignore inconsistent native results. Preserve WebKit creation and null lookup
compatibility, with regression tests beside the alarm methods.

BREAKING CHANGE: clearAllAlarm now reports whether the collection observed
before deletion was nonempty. An empty Chromium collection returns false
instead of the previous native true. Reads and deletion are not atomic.
Use WebKit details objects, numeric Chrome and Firefox arguments, and the
Firefox Promise interface while retaining the selected native receiver.
Normalize null current-tab results, preserve cookie details or null, and name
missing native methods without losing callback errors. Select the manifest
action namespace in diagnostics and reject unsupported getBrowserInfo calls.

BREAKING CHANGE: removeCookie returns CookieDetails | null. Handle absent
results. Unsupported getBrowserInfo calls reject a Promise instead of throwing
synchronously; guarded missing methods use API-named Error objects instead
of native TypeError messages.
Exercise the production package with native WKWebExtension APIs and disposable
data stores. Record actual system versions and verify scheduling, repeated
conditional creation, removal, action state, missing results and errors.
Run strict true/false alarm removal assertions and action/result regressions
in the production Chromium and Firefox extension runners.
@atldays atldays closed this Nov 5, 2026
@addon-owner
addon-owner deleted the codex/safari-api-compatibility branch November 5, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant