Repository navigation
feat(core): frame.origin = 'call' marker (async origin capture, step 1) #176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f52f9db
5aef99e
3e5a899
5021031
55b22ce
7feda84
fca6922
a180d1b
db6be29
465bc6b
e3c4a5c
5e3753c
ec53291
cfac5c0
f6955b1
fec4393
7b76020
cb1bed6
b4862b2
0c84050
3b53f98
a79bd34
e5b79f3
92e0257
795182d
6e1b891
bafd953
ef03270
a234b83
7e73c92
57bbfb3
4446468
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,11 +4,77 @@ | |
| // a UI renderer). The Integration injects `injectScript('page', "import { registerClient } … registerClient(…)")`. | ||
| // | ||
| // Browser-only → behind the `@bugsee/astro/client` subpath, never the portable `.`/`./middleware` entries. | ||
| import { type Bugsee, type BugseeLaunchOptionsWithPerformance, launch } from '@bugsee/bugsee'; | ||
| import { | ||
| type Bugsee, | ||
| type BugseeLaunchOptionsWithPerformance, | ||
| launch, | ||
| relaunch as umbrellaRelaunch, | ||
| } from '@bugsee/bugsee'; | ||
| import { flushQueuedAstroHydrationErrors, listenForAstroHydrationErrors } from './hydration'; | ||
|
|
||
| /** Options for the Astro client (browser) composition — the batteries-included browser umbrella options. */ | ||
| export interface AstroClientOptions extends BugseeLaunchOptionsWithPerformance {} | ||
|
|
||
| // The hydration listener's options: where to report a failing sink, and which carrier the client lives on (a custom one is not on `globalThis`). | ||
| const hydrationOptions = ( | ||
| options: | ||
| | { | ||
| onError?: (error: unknown) => void; | ||
| carrier?: object; | ||
| document?: Document; | ||
| window?: unknown; | ||
| } | ||
| | undefined, | ||
| ) => { | ||
| // The page document the launch itself uses: an explicit `document`, else the bound window's. Omitted when neither yields one, which | ||
| // keeps the listener's default (`globalThis.document`). A hostile `window.document` getter (a sandboxed frame) counts as none. | ||
| let target: Document | undefined = options?.document; | ||
| if (target === undefined) { | ||
| try { | ||
| target = (options?.window as { document?: Document } | undefined)?.document; | ||
| } catch { | ||
| target = undefined; | ||
| } | ||
| } | ||
| return { | ||
| ...(options?.onError !== undefined ? { onError: options.onError } : {}), | ||
| ...(options?.carrier !== undefined ? { carrier: options.carrier } : {}), | ||
| ...(target !== undefined ? { target } : {}), | ||
|
cursor[bot] marked this conversation as resolved.
Resolved
|
||
| }; | ||
| }; | ||
|
|
||
| // The hydration options of the last registration (see `withHydrationWindow`). | ||
| let lastHydration: ReturnType<typeof hydrationOptions> = {}; | ||
|
|
||
| /** | ||
| * Open the hydration listener's launch window, run `start`, and close the window in a `finally`: an error dispatched while the client is | ||
| * (re)starting is queued, and the flush runs whether the start succeeded or failed. | ||
| */ | ||
| async function withHydrationWindow<T>( | ||
| options: | ||
| | { | ||
| onError?: (error: unknown) => void; | ||
| carrier?: object; | ||
| document?: Document; | ||
| window?: unknown; | ||
| } | ||
| | undefined, | ||
| start: () => Promise<T>, | ||
| ): Promise<T> { | ||
| // Like core's `relaunchWith`, which keeps `document`, `window`, `carrier` and `onError` from the previous launch and lets an explicit one | ||
| // win: a plain `relaunch()` must watch the same document, on the same carrier, with the same sink. | ||
| const hydration = { ...lastHydration, ...hydrationOptions(options) }; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Severity: P3 Low Problem: The merge happens on the resolved Scenario:
Impact: This is the same class as the case Fix: Remember the raw
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Acknowledged and deferred as a follow-up: the scenario needs an explicit |
||
| lastHydration = hydration; | ||
| // Astro swallows an island's hydration failure into an `astro:hydration-error` event; nothing else would see it. Listen BEFORE the | ||
| // launch resolves (an error dispatched meanwhile is queued) and flush once the client exists. | ||
| listenForAstroHydrationErrors(hydration); | ||
| try { | ||
| return await start(); | ||
| } finally { | ||
| flushQueuedAstroHydrationErrors(hydration); // success: report what queued; failure: end the window, nothing to report to | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Start Bugsee for the Astro client (browser). Returns the started client (a per-isolate singleton — a | ||
| * repeat call returns the existing client). | ||
|
cursor[bot] marked this conversation as resolved.
Resolved
|
||
|
|
@@ -17,7 +83,15 @@ export async function registerClient( | |
| appToken: string, | ||
| options: AstroClientOptions = {}, | ||
| ): Promise<Bugsee> { | ||
| return await launch(appToken, options); | ||
| return await withHydrationWindow(options, () => launch(appToken, options)); | ||
| } | ||
|
|
||
| /** | ||
| * `relaunch` from the umbrella, inside the same window: it `stop()`s the running client (clearing the carrier slot) and waits out the | ||
| * drain before the new one is set, and an island that fails to hydrate meanwhile must not be lost. | ||
| */ | ||
| export async function relaunch(options?: Parameters<typeof umbrellaRelaunch>[0]): Promise<Bugsee> { | ||
| return await withHydrationWindow(options, () => umbrellaRelaunch(options)); | ||
|
krassx marked this conversation as resolved.
Resolved
cursor[bot] marked this conversation as resolved.
Resolved
cursor[bot] marked this conversation as resolved.
Resolved
cursor[bot] marked this conversation as resolved.
Resolved
cursor[bot] marked this conversation as resolved.
Resolved
krassx marked this conversation as resolved.
Resolved
|
||
| } | ||
|
|
||
| // API parity with the umbrella entries: the same VALUE surface, thin re-exports of the same functions. | ||
|
|
@@ -30,5 +104,4 @@ export { | |
| type LifecycleEventsListener, | ||
| type LifecycleEventType, | ||
| type ReportAttachmentInput, | ||
| relaunch, | ||
| } from '@bugsee/bugsee'; | ||
Uh oh!
There was an error while loading. Please reload this page.