effect-browser 0.3.0-beta.15 → 0.3.0-beta.16
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 +6 -2
- package/dist/{Browser-BBSySyjT.mjs → Browser-DRPthkNO.mjs} +4 -4
- package/dist/Browser-DRPthkNO.mjs.map +1 -0
- package/dist/Browser.d.mts +2 -2
- package/dist/Browser.mjs +1 -1
- package/dist/{BrowserEvent-BRu2juEz.d.mts → BrowserEvent-dq6FRT8w.d.mts} +9 -9
- package/dist/BrowserEvent.d.mts +1 -1
- package/dist/BrowserEvent.mjs +7 -12
- package/dist/BrowserEvent.mjs.map +1 -1
- package/dist/Cdp.mjs +2 -2
- package/dist/{Change-iMlcuzVD.d.mts → Change-DqING3tr.d.mts} +2 -2
- package/dist/Change.d.mts +1 -1
- package/dist/Chromium.mjs +2 -2
- package/dist/Expect.d.mts +1 -1
- package/dist/Expect.mjs +2 -2
- package/dist/Moment.d.mts +1 -1
- package/dist/Moment.mjs +1 -1
- package/dist/Motion-DND6I-64.d.mts +40 -0
- package/dist/Motion.d.mts +2 -40
- package/dist/Motion.mjs +1 -2
- package/dist/Motion.mjs.map +1 -1
- package/dist/{Page-B5cjaUp5.mjs → Page-C_VkBVwI.mjs} +5 -9
- package/dist/Page-C_VkBVwI.mjs.map +1 -0
- package/dist/{Page-DL9eylp3.d.mts → Page-jHmSJeOS.d.mts} +6 -13
- package/dist/Page.d.mts +1 -1
- package/dist/Page.mjs +1 -1
- package/dist/{Plan-6As6vcwT.d.mts → Plan-DLtRksuu.d.mts} +3 -3
- package/dist/{Plan-CXA2BW-G.mjs → Plan-X-JkACAB.mjs} +6 -9
- package/dist/Plan-X-JkACAB.mjs.map +1 -0
- package/dist/Plan.d.mts +1 -1
- package/dist/Plan.mjs +1 -1
- package/dist/Policy.d.mts +1 -1
- package/dist/Policy.mjs +1 -1
- package/dist/Presentation.d.mts +2 -2
- package/dist/Presentation.mjs +3 -2
- package/dist/Presentation.mjs.map +1 -1
- package/dist/Stage.d.mts +1 -1
- package/dist/Stage.mjs +3 -3
- package/dist/Stage.mjs.map +1 -1
- package/dist/{Supervisor-DaGlQVjv.mjs → Supervisor-BgWP8o9t.mjs} +41 -17
- package/dist/Supervisor-BgWP8o9t.mjs.map +1 -0
- package/dist/{Supervisor-5tZ47hR5.d.mts → Supervisor-mVPeEUp8.d.mts} +12 -5
- package/dist/Supervisor.d.mts +1 -1
- package/dist/Supervisor.mjs +1 -1
- package/dist/{context-BAjRj7Xo.mjs → context-rYTk-3Cv.mjs} +68 -3
- package/dist/context-rYTk-3Cv.mjs.map +1 -0
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +4 -4
- package/dist/match.inpage-xOe9LNO0.mjs.map +1 -1
- package/dist/{page-B92QnRfT.mjs → page-ClEMFnBG.mjs} +48 -110
- package/dist/page-ClEMFnBG.mjs.map +1 -0
- package/package.json +1 -1
- package/src/Browser.ts +1 -1
- package/src/BrowserEvent.ts +7 -12
- package/src/Motion.ts +1 -2
- package/src/Page.ts +5 -9
- package/src/Plan.ts +1 -2
- package/src/Presentation.ts +2 -1
- package/src/Stage.ts +2 -1
- package/src/Supervisor.ts +3 -2
- package/src/internal/input/actions.ts +25 -33
- package/src/internal/input/dispatch.ts +3 -4
- package/src/internal/input/edit.inpage.ts +3 -9
- package/src/internal/input/evidence.inpage.ts +2 -20
- package/src/internal/input/guard.inpage.ts +9 -29
- package/src/internal/input/guard.ts +12 -1
- package/src/internal/input/targets.inpage.ts +4 -8
- package/src/internal/input/targets.ts +8 -11
- package/src/internal/page/context.ts +2 -2
- package/src/internal/pictures/capture.ts +4 -4
- package/src/internal/pictures/clock.ts +8 -3
- package/src/internal/pictures/pictures.ts +2 -1
- package/src/internal/reading/controls.inpage.ts +8 -1
- package/src/internal/reading/match.inpage.ts +2 -1
- package/src/internal/reading/outline.inpage.ts +7 -4
- package/src/internal/reading/reading.ts +5 -16
- package/src/internal/supervisor/lifecycle.ts +56 -13
- package/dist/Browser-BBSySyjT.mjs.map +0 -1
- package/dist/Page-B5cjaUp5.mjs.map +0 -1
- package/dist/Plan-CXA2BW-G.mjs.map +0 -1
- package/dist/Supervisor-DaGlQVjv.mjs.map +0 -1
- package/dist/context-BAjRj7Xo.mjs.map +0 -1
- package/dist/page-B92QnRfT.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Page-B5cjaUp5.mjs","names":["Fact","Guard.Fact","Url.withheld"],"sources":["../src/internal/input/evidence.inpage.ts","../src/internal/input/guard.inpage.ts","../src/Page.ts"],"sourcesContent":["/**\n * In the page: what the page says about an input's first target, for a judge, and which fields a\n * form would send. It never reads what a field holds. See `reading/names.inpage.ts` for what a page-side part may use.\n */\nimport { Schema } from \"effect\";\n\nimport type { ContextReader } from \"../reading/context.inpage.ts\";\nimport type { Names } from \"../reading/names.inpage.ts\";\n\nexport interface FormField {\n readonly type: string;\n readonly name: string;\n readonly autocomplete?: string | undefined;\n readonly filled: boolean;\n}\n\n/** Page text about the first target. It never includes what a field holds. */\nexport interface Evidence {\n readonly title: string;\n readonly description?: string | undefined;\n readonly dialog?: string | undefined;\n readonly heading?: string | undefined;\n readonly nearby?: string | undefined;\n readonly form?:\n | {\n readonly method: string;\n readonly action: string;\n readonly fields: ReadonlyArray<FormField>;\n }\n | undefined;\n}\n\ntype Field = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;\n\nexport const evidence = (names: Names, placing: ContextReader) => {\n const { clean, isDocument, isInput, isSelect, isTextArea, nameOf, parentOf, roleOf, textOf } =\n names;\n\n const { groups, headingBefore, textBeside, treeOf } = placing;\n\n /** A field a submission would send. */\n const isField = (element: Element): element is Field =>\n ((isInput(element) && ![\"button\", \"submit\", \"reset\", \"image\"].includes(element.type)) ||\n isSelect(element) ||\n isTextArea(element)) &&\n !element.matches(\":disabled\");\n\n const isFilled = (field: Field): boolean =>\n isInput(field) && (field.type === \"checkbox\" || field.type === \"radio\")\n ? field.checked\n : isInput(field) && field.type === \"file\"\n ? (field.files?.length ?? 0) > 0\n : field.value !== \"\";\n\n const dialogOf = (element: Element): Element | undefined => {\n for (let node: Element | null = element; node !== null; node = parentOf(node))\n if (node.tagName === \"DIALOG\" || /^(?:alert)?dialog$/.test(node.getAttribute(\"role\") ?? \"\"))\n return node;\n\n return undefined;\n };\n\n /** What the page says about an input's first target, for a judge. Never a field's value. */\n const evidenceOf = (\n element: Element,\n form: HTMLFormElement | null,\n method: string | undefined,\n action: string | undefined,\n ): Evidence => {\n const name = nameOf(element, roleOf(element));\n const ids = element.getAttribute(\"aria-describedby\");\n\n const description = clean(\n ids === null\n ? (element.getAttribute(\"aria-description\") ?? element.getAttribute(\"title\"))\n : ids\n .split(/\\s+/)\n .map((id) => element.ownerDocument.getElementById(id)?.textContent ?? \"\")\n .join(\" \"),\n 120,\n );\n\n const dialog = dialogOf(element);\n\n const title = dialog?.querySelector(\"h1,h2,h3,h4,h5,h6,[role=heading]\");\n\n const dialogName =\n dialog === undefined\n ? \"\"\n : clean(nameOf(dialog, \"dialog\"), 120) ||\n (title === null || title === undefined ? \"\" : clean(textOf(title), 120));\n\n // Each scope stays in the target's own tree: a walker cannot leave a shadow root.\n const root = element.getRootNode();\n const top = isDocument(root) ? (root.body ?? root) : root;\n const inTree = element.closest(\"dialog,[role=dialog],[role=alertdialog]\");\n let nearby = \"\";\n\n for (const scope of new Set([element.closest(groups), inTree, top]))\n if (scope !== null && nearby === \"\")\n nearby = textBeside(element, scope, true) || textBeside(element, scope, false);\n\n const heading = headingBefore(element, treeOf(element));\n\n const fields =\n form === null\n ? []\n : Array.from(form.elements)\n .filter(isField)\n .slice(0, 16)\n .map((field) => {\n const autocomplete = clean(field.getAttribute(\"autocomplete\"), 40);\n\n return {\n type: isInput(field) ? field.type : field.tagName.toLowerCase(),\n name: clean(\n isInput(field) && field.type === \"hidden\"\n ? field.getAttribute(\"name\")\n : nameOf(field, roleOf(field)),\n 40,\n ),\n ...(autocomplete === \"\" ? {} : { autocomplete }),\n filled: isFilled(field),\n };\n });\n\n return {\n title: clean(document.title, 120),\n ...(description === \"\" || description === name ? {} : { description }),\n ...(dialogName === \"\" ? {} : { dialog: dialogName }),\n ...(heading === undefined ? {} : { heading }),\n ...(nearby === \"\" ? {} : { nearby }),\n ...(form === null\n ? {}\n : { form: { method: method ?? form.method, action: action ?? form.action, fields } }),\n };\n };\n\n return { evidenceOf, isField, isFilled };\n};\n\nexport type EvidenceReader = ReturnType<typeof evidence>;\n\nexport const FormFieldSchema = Schema.Struct({\n type: Schema.String,\n name: Schema.String,\n autocomplete: Schema.optional(Schema.String),\n filled: Schema.Boolean,\n});\n\nexport const EvidenceSchema = Schema.Struct({\n title: Schema.String,\n description: Schema.optional(Schema.String),\n dialog: Schema.optional(Schema.String),\n heading: Schema.optional(Schema.String),\n nearby: Schema.optional(Schema.String),\n form: Schema.optional(\n Schema.Struct({\n method: Schema.String,\n action: Schema.String,\n fields: Schema.Array(FormFieldSchema),\n }),\n ),\n});\n","/**\n * In the page: what the input guard decides on. It inspects an input's targets for the facts a\n * policy weighs, such as a form submission or a secret field, binds an approval to them, and\n * checks before each press that the approved target would still receive it. See `reading/names.inpage.ts` for what a page-side part may use.\n */\nimport { Schema } from \"effect\";\n\nimport type { Names } from \"../reading/names.inpage.ts\";\nimport { type Evidence, type EvidenceReader, EvidenceSchema } from \"./evidence.inpage.ts\";\nimport type { Targets } from \"./targets.inpage.ts\";\n\nexport const Fact = Schema.Literals([\n \"form-submit\",\n \"cross-origin\",\n \"download\",\n \"upload\",\n \"secret\",\n \"scripted\",\n \"opaque\",\n]);\n\nexport type Fact = typeof Fact.Type;\n\nexport interface InputPlan {\n readonly action: string;\n readonly targets: ReadonlyArray<string | { readonly x: number; readonly y: number } | null>;\n readonly submit: boolean;\n readonly keys: string | null;\n readonly destination: string | null;\n}\n\nexport interface InspectedTarget {\n readonly ref: string;\n readonly element: string;\n readonly role: string | null;\n readonly name: string;\n readonly cursor: string;\n readonly href?: string | undefined;\n /** A field the DOM marks as holding a password, a one-time code or a card's details. */\n readonly secret: boolean;\n readonly fingerprint: string;\n}\n\nexport interface PreparedInput {\n readonly url: string;\n readonly targets: ReadonlyArray<InspectedTarget | null>;\n readonly facts: ReadonlyArray<Fact>;\n readonly destination?: string | undefined;\n readonly evidence: Evidence;\n}\n\n/** A refusal; a stale target is named by its index in the plan. */\nexport interface InputFailure {\n readonly error: string;\n readonly detail: string;\n readonly index?: number | undefined;\n}\n\nexport type PreparedInputResult = PreparedInput | InputFailure;\n\nexport type ValidatedInputResult = { readonly ok: true } | InputFailure;\n\n/** A point where a target, by its index in the plan, is about to receive a press. */\nexport interface Press {\n readonly index: number;\n readonly x: number;\n readonly y: number;\n}\n\nexport interface ValidationOptions {\n /** Require focus on the first target. */\n readonly focused?: boolean;\n /** After the pointer's own events have run, each target must still receive its press. */\n readonly presses?: ReadonlyArray<Press>;\n}\n\nexport const guard = (names: Names, targets: Targets, evidence: EvidenceReader) => {\n const {\n activeElement,\n clean,\n describe,\n inCurrentDocument,\n interactiveRoles,\n isButton,\n isDisabled,\n isHtml,\n isInput,\n isLabel,\n isRoot,\n isSecret,\n isSelect,\n isTextArea,\n lookup,\n parentOf,\n refFor,\n roleOf,\n } = names;\n\n const { controlOf, details, hitAt, hrefAttribute, linkOf, receives, within } = targets;\n const { evidenceOf, isField, isFilled } = evidence;\n\n /**\n * The element whose activation behaviour a click or key on `element` runs, as the browser\n * resolves it along the composed path: a link, button, input, summary or a label's control.\n */\n const activationTarget = (element: Element): Element | undefined => {\n for (let node: Element | null = element; node !== null; node = parentOf(node)) {\n if (\n hrefAttribute(node) !== null ||\n node.tagName === \"BUTTON\" ||\n node.tagName === \"SUMMARY\" ||\n (isInput(node) && node.type !== \"hidden\")\n )\n return node;\n if (isLabel(node) && node.control !== null) return node.control;\n }\n\n return undefined;\n };\n\n /**\n * A control between a press's hit and the approved target that is not the target's own\n * activation, such as a link or button a hover handler nested into it. The approval inspected\n * the target, so that control would act unapproved.\n */\n const nestedControl = (element: Element, hit: Element): Element | undefined => {\n // A container of the target is covered by the target's own facts.\n if (!within(element, hit)) return undefined;\n const own = activationTarget(element);\n\n for (\n let node: Element | null = hit;\n node !== null && node !== element;\n node = parentOf(node) ?? node.ownerDocument.defaultView?.frameElement ?? null\n )\n if (\n node !== own &&\n (hrefAttribute(node) !== null ||\n node.tagName === \"BUTTON\" ||\n node.tagName === \"SUMMARY\" ||\n (isInput(node) && node.type !== \"hidden\") ||\n isSelect(node) ||\n isTextArea(node) ||\n (isLabel(node) && node.control !== null && node.control !== own) ||\n activatingRoles.has(roleOf(node) ?? \"\"))\n )\n return node;\n\n return undefined;\n };\n\n const textEntry = (element: Element): boolean =>\n (isInput(element) &&\n ![\n \"button\",\n \"reset\",\n \"submit\",\n \"image\",\n \"checkbox\",\n \"radio\",\n \"file\",\n \"range\",\n \"color\",\n \"hidden\",\n ].includes(element.type)) ||\n isTextArea(element) ||\n (isHtml(element) && element.isContentEditable);\n\n const activatingRoles = new Set([\n \"button\",\n \"link\",\n \"checkbox\",\n \"radio\",\n \"switch\",\n \"tab\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"option\",\n \"treeitem\",\n ]);\n\n // Typed text goes wherever focus is, and a typed space or letter can press a focused button,\n // toggle a box, follow a link or change a select. Only fields, or elements that are none of\n // these (a page or a canvas game), may receive text.\n const typingRefusal = (element: Element, explicit: boolean): string | undefined =>\n textEntry(element)\n ? undefined\n : explicit\n ? `${describe(element)} is not a text field`\n : activationTarget(element) !== undefined ||\n isSelect(element) ||\n activatingRoles.has(roleOf(element) ?? \"\")\n ? `focus is on ${describe(element)}, which typed text could activate or change; type into a text field by ref, or use press for keys`\n : undefined;\n\n const isSubmitter = (element: Element): element is HTMLButtonElement | HTMLInputElement =>\n (isButton(element) && element.type === \"submit\") ||\n (isInput(element) && (element.type === \"submit\" || element.type === \"image\"));\n\n // form.elements omits image submitters. Walk the whole root in tree order so an Enter\n // submission uses the real default button, including controls associated from outside the form.\n const defaultSubmitter = (form: HTMLFormElement) => {\n const root = form.getRootNode();\n\n return isRoot(root)\n ? Array.from(root.querySelectorAll(\"button,input\")).find(\n (candidate): candidate is HTMLButtonElement | HTMLInputElement =>\n isSubmitter(candidate) && candidate.form === form,\n )\n : undefined;\n };\n\n // Attributes that say what a field is for. They bind an approval.\n const purpose = (control: Element, form: HTMLFormElement | null) => [\n control.getAttribute(\"id\"),\n control.getAttribute(\"name\"),\n control.getAttribute(\"inputmode\"),\n control.getAttribute(\"autocomplete\"),\n control.getAttribute(\"aria-label\"),\n form?.getAttribute(\"id\"),\n form?.getAttribute(\"name\"),\n form?.getAttribute(\"aria-label\"),\n ];\n\n // What an approval binds of a URL. A fragment that names a place on the page, which scroll-spy\n // and feed pages rewrite as they scroll, is left out. A hash route (#/… or #!…) stays: it\n // selects what the page's controls act on.\n const boundUrl = (url: string): string => {\n const hash = url.indexOf(\"#\");\n\n return hash === -1 || /^#[/!]/.test(url.slice(hash)) ? url : url.slice(0, hash);\n };\n\n const inspectInput = (element: Element, plan: InputPlan) => {\n const metadata = details(element, element, 0, 0);\n // Facts are about what the input activates, such as the submit button around a painted label.\n const control = activationTarget(element) ?? element;\n\n const form =\n isInput(control) || isButton(control) || isTextArea(control) || isSelect(control)\n ? control.form\n : null;\n\n // The chord's last key, which may be the plus key itself: Control++.\n const key = plan.keys === null ? undefined : /(?:^|\\+)(\\+|[^+]+)$/.exec(plan.keys)?.[1];\n const enter = key === \"Enter\";\n\n const activation =\n plan.action === \"click\" || (plan.action === \"press\" && (enter || key === \"Space\"));\n\n // Enter submits a form from any input but buttons, file and color pickers, including\n // checkboxes, radios and ranges.\n const fieldEnter =\n isInput(control) &&\n ![\"button\", \"reset\", \"submit\", \"image\", \"file\", \"color\", \"hidden\"].includes(control.type) &&\n ((plan.action === \"press\" && enter) || (plan.action === \"type\" && plan.submit));\n\n const submits = form !== null && ((activation && isSubmitter(control)) || fieldEnter);\n\n const submitter = isSubmitter(control)\n ? control\n : form === null\n ? undefined\n : defaultSubmitter(form);\n\n const formDestination =\n form === null\n ? undefined\n : submitter?.hasAttribute(\"formaction\") === true\n ? submitter.formAction\n : form.action;\n\n const formMethod =\n form === null\n ? undefined\n : submitter?.hasAttribute(\"formmethod\") === true\n ? submitter.formMethod\n : form.method;\n\n const formTarget =\n form === null\n ? undefined\n : submitter?.hasAttribute(\"formtarget\") === true\n ? submitter.formTarget\n : form.target;\n\n const link = linkOf(element);\n const href = link === undefined ? null : hrefAttribute(link);\n // A dialog form only closes its dialog; the page's script decides what that means.\n const sends = submits && formMethod !== \"dialog\";\n // Only activation follows a link or opens a file chooser; hovering or scrolling over a\n // control does neither.\n const destination = sends ? formDestination : activation ? metadata.href : undefined;\n const acts = plan.action !== \"hover\" && plan.action !== \"scroll\";\n\n // What the browser itself does on activation: follow a link, submit or reset a form, choose\n // a file or a value, toggle a box or a disclosure, or focus a field. Anything else is the\n // page's script.\n const builtIn =\n sends ||\n (href !== null && !/^\\s*(?:#\\s*|javascript:[^]*)$/i.test(href)) ||\n (isInput(control) && ![\"button\", \"submit\", \"image\", \"reset\"].includes(control.type)) ||\n ((isInput(control) || isButton(control)) && control.type === \"reset\" && form !== null) ||\n control.tagName === \"SUMMARY\" ||\n control.closest(\"select\") !== null ||\n textEntry(control);\n\n const facts: Array<Fact> = [];\n\n // Facts come from structure only. What a name or the text around it says is evidence for a\n // judge, never a fact: words change meaning with context and language.\n if (sends) facts.push(\"form-submit\");\n if (activation && link?.hasAttribute(\"download\") === true) facts.push(\"download\");\n if (activation && isInput(control) && control.type === \"file\") facts.push(\"upload\");\n if (\n (plan.action === \"type\" && isSecret(control)) ||\n (sends &&\n form !== null &&\n Array.from(form.elements).some(\n (field) => isField(field) && isSecret(field) && isFilled(field),\n ))\n )\n facts.push(\"secret\");\n if (activation && !builtIn) facts.push(\"scripted\");\n if (acts && (metadata.role === \"canvas\" || metadata.role === \"iframe\" || metadata.name === \"\"))\n facts.push(\"opaque\");\n\n // Bind what decides the consequence and the control's identity. Names bind interactive\n // controls only: other text, such as a live price or a page's own text, may change freely.\n const role = metadata.role;\n\n const boundName =\n role !== null &&\n (interactiveRoles.has(role) || role === \"canvas\" || role === \"iframe\") &&\n !(isHtml(element) && element.isContentEditable)\n ? metadata.name\n : null;\n\n // A focus or scroll handler changing these attributes must not leave an old permission behind.\n const fingerprint = JSON.stringify([\n purpose(control, form),\n element.tagName,\n element.id,\n role,\n boundName,\n metadata.href,\n control === element ? null : refFor(control),\n isInput(control) || isButton(control) ? control.type : control.tagName,\n control.matches(\":disabled\") || isDisabled(control),\n control.getAttribute(\"readonly\"),\n control.getAttribute(\"aria-readonly\"),\n isHtml(control) && control.isContentEditable,\n control.getAttribute(\"name\"),\n control.getAttribute(\"accept\"),\n control.hasAttribute(\"multiple\"),\n link?.getAttribute(\"download\"),\n form === null ? null : refFor(form),\n form === null ? null : boundUrl(form.action),\n form?.method,\n form?.target,\n submitter === undefined ? null : refFor(submitter),\n formDestination === undefined ? undefined : boundUrl(formDestination),\n formMethod,\n formTarget,\n submitter?.formNoValidate,\n form?.noValidate,\n ]);\n\n const inspected: InspectedTarget = {\n ref: refFor(element),\n element: metadata.element,\n role: metadata.role,\n name: metadata.name,\n cursor: metadata.cursor,\n ...(metadata.href === undefined ? {} : { href: metadata.href }),\n secret: isSecret(control),\n fingerprint,\n };\n\n return {\n inspected,\n facts,\n destination,\n explain: () => evidenceOf(element, form, formMethod, formDestination),\n };\n };\n\n // Approval preparation only reads the DOM. In particular, an offscreen ref must not scroll\n // before the policy has had a chance to deny it.\n const inspect = (\n plan: InputPlan,\n ): (Omit<PreparedInput, \"evidence\"> & { readonly explain: () => Evidence }) | InputFailure => {\n const targets: Array<InspectedTarget | null> = [];\n const facts = new Set<Fact>();\n let destination = plan.destination ?? undefined;\n let explain = (): Evidence => ({ title: clean(document.title, 120) });\n\n for (const [index, target] of plan.targets.entries()) {\n let element: Element | null | undefined;\n\n if (target === null) {\n element = activeElement();\n } else if (typeof target === \"string\") {\n element = lookup(target);\n if (element === undefined)\n return { error: \"stale\", detail: target + \" is not on the page any more\", index };\n } else {\n if (\n !Number.isFinite(target.x) ||\n !Number.isFinite(target.y) ||\n target.x < 0 ||\n target.y < 0 ||\n target.x >= window.innerWidth ||\n target.y >= window.innerHeight\n )\n return { error: \"outside\", detail: \"the point is outside the viewport\" };\n const hit = hitAt(document, target.x, target.y);\n\n element = hit === null ? null : controlOf(hit);\n if (element === null)\n return { error: \"offscreen\", detail: \"nothing is painted at the point\" };\n }\n\n if (element === null) {\n targets.push(null);\n continue;\n }\n if (!inCurrentDocument(element))\n return { error: \"stale\", detail: \"the input target belongs to a replaced document\", index };\n const refusal = plan.action === \"type\" ? typingRefusal(element, target !== null) : undefined;\n\n if (refusal !== undefined) return { error: \"untypeable\", detail: refusal };\n const inspected = inspectInput(element, plan);\n\n if (index === 0) explain = inspected.explain;\n targets.push(inspected.inspected);\n for (const fact of inspected.facts) facts.add(fact);\n destination ??= inspected.destination;\n if (inspected.destination !== undefined) {\n try {\n if (new URL(inspected.destination, location.href).origin !== location.origin)\n facts.add(\"cross-origin\");\n } catch {\n return { error: \"outside\", detail: \"the input destination is not a valid URL\" };\n }\n }\n }\n\n if (destination !== undefined) {\n try {\n destination = new URL(destination, location.href).href;\n if (new URL(destination).origin !== location.origin) facts.add(\"cross-origin\");\n } catch {\n return { error: \"outside\", detail: \"the input destination is not a valid URL\" };\n }\n }\n\n return {\n url: boundUrl(location.href),\n targets,\n facts: [...facts],\n ...(destination === undefined ? {} : { destination }),\n explain,\n };\n };\n\n // Evidence is read once, for the policy. Validation binds the facts and the targets, not the\n // text around them, which live pages change freely.\n const prepareInput = (plan: InputPlan): PreparedInputResult => {\n const inspected = inspect(plan);\n\n if (\"error\" in inspected) return inspected;\n const { explain, ...prepared } = inspected;\n\n return { ...prepared, evidence: explain() };\n };\n\n const validate = (\n plan: InputPlan,\n prepared: PreparedInput,\n options: ValidationOptions,\n ): ValidatedInputResult => {\n const current = inspect(plan);\n\n if (\"error\" in current)\n return current.error === \"stale\" ? current : { error: \"changed\", detail: current.detail };\n if (\n current.url !== prepared.url ||\n (current.destination === undefined || prepared.destination === undefined\n ? current.destination !== prepared.destination\n : boundUrl(current.destination) !== boundUrl(prepared.destination)) ||\n JSON.stringify(current.facts) !== JSON.stringify(prepared.facts) ||\n current.targets.length !== prepared.targets.length ||\n current.targets.some((target, index) => {\n const previous = prepared.targets[index];\n\n return target === null\n ? previous !== null\n : previous === null ||\n previous === undefined ||\n target.ref !== previous.ref ||\n target.fingerprint !== previous.fingerprint;\n })\n )\n return {\n error: \"changed\",\n detail: \"the page or input target changed while the policy was deciding\",\n };\n\n if (options.focused === true) {\n const active = activeElement();\n const expected = prepared.targets[0];\n\n if (\n active === null ||\n expected === null ||\n expected === undefined ||\n refFor(active) !== expected.ref\n )\n return { error: \"changed\", detail: \"focus moved away from the approved element\" };\n }\n\n for (const press of options.presses ?? []) {\n const expected = prepared.targets[press.index];\n\n const element =\n expected === null || expected === undefined ? undefined : lookup(expected.ref);\n\n const hit = hitAt(document, press.x, press.y);\n\n if (element === undefined || hit === null || !receives(element, hit))\n return {\n error: \"changed\",\n detail: `the approved target is no longer under the pointer at (${press.x}, ${press.y})`,\n };\n\n const nested = nestedControl(element, hit);\n\n if (nested !== undefined)\n return {\n error: \"changed\",\n detail: `${describe(nested)} inside the approved target would receive the press at (${press.x}, ${press.y})`,\n };\n }\n\n return { ok: true };\n };\n\n // Chromium delivers pointer moves with the next frame. A press check waits until the frame\n // after it, so it sees what the page did when the pointer arrived, such as a menu opened over\n // the target. A hidden document draws no frames, and its moves wait for the press instead.\n const validateInput = (\n plan: InputPlan,\n prepared: PreparedInput,\n options: ValidationOptions = {},\n ): ValidatedInputResult | Promise<ValidatedInputResult> => {\n if ((options.presses ?? []).length === 0) return validate(plan, prepared, options);\n const { promise, resolve } = Promise.withResolvers<void>();\n\n if (document.visibilityState === \"hidden\") resolve();\n else requestAnimationFrame(() => requestAnimationFrame(() => resolve()));\n\n return promise.then(() => validate(plan, prepared, options));\n };\n\n return { prepareInput, textEntry, typingRefusal, validateInput };\n};\n\nexport type Guard = ReturnType<typeof guard>;\n\nconst InputPreparationError = Schema.Struct({\n error: Schema.String,\n detail: Schema.String,\n index: Schema.optional(Schema.Finite),\n});\n\nexport const PreparedInputResultSchema = Schema.Union([\n Schema.Struct({\n url: Schema.String,\n targets: Schema.Array(\n Schema.NullOr(\n Schema.Struct({\n ref: Schema.String,\n element: Schema.String,\n role: Schema.NullOr(Schema.String),\n name: Schema.String,\n cursor: Schema.String,\n href: Schema.optional(Schema.String),\n secret: Schema.Boolean,\n fingerprint: Schema.String,\n }),\n ),\n ),\n facts: Schema.Array(Fact),\n destination: Schema.optional(Schema.String),\n evidence: EvidenceSchema,\n }),\n InputPreparationError,\n]);\n\nexport const ValidatedInputResultSchema = Schema.Union([\n Schema.Struct({ ok: Schema.Literal(true) }),\n InputPreparationError,\n]);\n","/**\n * One browser tab: navigation, snapshots, pictures and input.\n *\n * A page waits only for itself: its operations take turns in one lane of its own. An action, which\n * sends input or navigates, has the page to itself, in the order actions were asked; reads share\n * it, after the action in flight and every action asked before them, so a read describes the page\n * an action left. A wait for a turn ends at the operation's deadline as `Busy`, never `Timeout`,\n * and a full deadline then bounds the operation itself; `failFast` fails it at once instead.\n * Identical reads asked between the same actions share one call to the page, and one whose\n * callers gave up finishes for the next caller to ask it. A policy holds outside the lane while\n * other operations continue; its target is revalidated before dispatch. Element targets are refs\n * from a snapshot; point targets are viewport coordinates in CSS pixels, the same coordinates as a\n * screenshot's pixels. Mouse and keyboard input share a bounded pipeline, so pacing does not wait\n * for each protocol reply. Target lookup happens before the input is sent.\n *\n * @since 0.3.0\n */\nimport { type Duration, Effect, Schema, type Stream } from \"effect\";\nimport type { Page as PlaywrightPage } from \"playwright-core\";\n\nimport { type BrowserError, type PolicyDenied } from \"./BrowserError.ts\";\nimport { Box, type BrowserEvent, PageLoaded, Subject, SubjectContext } from \"./BrowserEvent.ts\";\nimport type { Changes } from \"./Change.ts\";\nimport { type CaptureStats, Frame, Image, type ScreencastOptions } from \"./Frame.ts\";\nimport { FormFieldSchema } from \"./internal/input/evidence.inpage.ts\";\nimport * as Guard from \"./internal/input/guard.inpage.ts\";\nimport { Correlation, FailFast } from \"./internal/page/lane.ts\";\nimport * as Url from \"./internal/page/url.ts\";\nimport type { Window } from \"./Moment.ts\";\nimport { type Snapshot, type SnapshotOptions } from \"./Snapshot.ts\";\n\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** A ref from a snapshot, such as `\"e12\"`, or a viewport point. */\nexport type Target = string | Point;\n\n/** An integer rectangle in viewport CSS pixels. */\nexport class Region extends Schema.Class<Region>(\"effect-browser/Region\")({\n x: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n y: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n width: Schema.Int.check(Schema.isGreaterThan(0)),\n height: Schema.Int.check(Schema.isGreaterThan(0)),\n}) {}\n\n/** A crop and its viewport origin: add that origin to a point read from the crop. */\nexport class Zoom extends Schema.Class<Zoom>(\"effect-browser/Zoom\")({\n page: Schema.String,\n region: Region,\n image: Image,\n}) {}\n\n/** The target as it read before input. Point coordinates are never snapped to another position. */\nexport class ResolvedTarget extends Schema.Class<ResolvedTarget>(\"effect-browser/ResolvedTarget\")({\n point: Schema.Struct({ x: Schema.Finite, y: Schema.Finite }),\n element: Schema.String,\n /** The element's lowercase tag name. */\n tag: Schema.String,\n role: Schema.NullOr(Schema.String),\n name: Schema.String,\n context: SubjectContext,\n /** For a point target, the box of what it found there. */\n box: Schema.optional(Box),\n cursor: Schema.String,\n href: Schema.optional(Schema.String),\n}) {}\n\nexport interface ClickOptions {\n readonly button?: \"left\" | \"right\" | \"middle\" | undefined;\n /** 2 for a double click. */\n readonly clickCount?: number | undefined;\n /** Hold the button down this long before releasing it. */\n readonly holdMillis?: number | undefined;\n}\n\nexport interface TypeOptions {\n /** Type into this text field: it is focused first, and its content replaced unless `replace` is false. */\n readonly into?: string | undefined;\n readonly replace?: boolean | undefined;\n /** Press Enter afterwards. */\n readonly submit?: boolean | undefined;\n /**\n * The text is a secret: type it only into a field the page marks secret, such as a password,\n * and otherwise refuse with `NotActionable` before any input. A replayed password asks this.\n */\n readonly secret?: boolean | undefined;\n}\n\nexport interface PressOptions {\n /**\n * Focus this element, by ref, before the first press: a link, a button or a field. The keys go to\n * whatever has focus otherwise.\n */\n readonly on?: string | undefined;\n /** Press the keys this many times. */\n readonly times?: number | undefined;\n /** Hold the keys down this long before releasing them, as a game control might need. */\n readonly holdMillis?: number | undefined;\n}\n\nexport interface ScrollOptions {\n readonly dx?: number | undefined;\n /** Pixels to scroll down; negative scrolls up. Defaults to most of a viewport. */\n readonly dy?: number | undefined;\n /** Scroll whatever is under this point or element. Defaults to the middle of the viewport. */\n readonly at?: Target | undefined;\n}\n\n/**\n * How current a picture must be. The newest screencast frame serves when it qualifies, at no cost;\n * otherwise a new screenshot is taken.\n */\nexport interface FrameOptions {\n /**\n * The oldest a reused frame may be, from its paint, at the earliest its timing allows, to now.\n * Defaults to 250 milliseconds; 0 always takes a new screenshot.\n */\n readonly maxAge?: Duration.Input | undefined;\n /**\n * `\"input\"`: reuse only a frame painted after this page's latest input, including input of an\n * interrupted action, and never while an action is changing the page. For a caller that has\n * just acted on the page.\n */\n readonly after?: \"input\" | undefined;\n}\n\n/** A screenshot reuses only a frame painted after the page's latest input, as `after: \"input\"`. */\nexport interface ScreenshotOptions {\n /** The oldest a reused frame may be, as for `frame`. Defaults to 250 milliseconds. */\n readonly maxAge?: Duration.Input | undefined;\n /** A region of the viewport, captured in CSS pixels at the viewport's own scale; always new. */\n readonly clip?:\n | { readonly x: number; readonly y: number; readonly width: number; readonly height: number }\n | undefined;\n /** JPEG quality, 0 to 100. Defaults to 80. */\n readonly quality?: number | undefined;\n /** `\"jpeg\"`, the default, or `\"png\"`, which is always a new picture. */\n readonly format?: \"jpeg\" | \"png\" | undefined;\n}\n\n/**\n * What `find` looks for. Every rule given must hold; with none, it finds every element in scope\n * that has a role or is a control.\n */\nexport interface FindQuery {\n /** An ARIA role, such as `\"button\"` or `\"heading\"`, ignoring case. */\n readonly role?: string | undefined;\n /**\n * The accessible name: a string that reads the same once spaces are collapsed and case folded,\n * or a pattern found in it.\n */\n readonly name?: string | RegExp | undefined;\n /**\n * Text it shows, ignoring case and spacing, or a pattern. Text inside a control or a heading is\n * that control's or heading's, and only the smallest element showing it matches, not every\n * element around it.\n */\n readonly text?: string | RegExp | undefined;\n /** Whole words in its context (row, column, label or heading), ignoring case and spacing. */\n readonly near?: string | undefined;\n /** Only what a point action at this viewport point would reach: the control there, or else what is painted there. */\n readonly at?: Point | undefined;\n /** The viewport (the default), or the whole document. */\n readonly scope?: \"viewport\" | \"document\" | undefined;\n}\n\n/**\n * An element's state as its markup gives it: `checked` for what can be checked, `expanded`,\n * `selected` and `pressed` where the page says either way, and `level` for headings.\n */\nexport const ElementState = Schema.Struct({\n disabled: Schema.Boolean,\n focused: Schema.Boolean,\n checked: Schema.optional(Schema.Boolean),\n expanded: Schema.optional(Schema.Boolean),\n selected: Schema.optional(Schema.Boolean),\n pressed: Schema.optional(Schema.Boolean),\n level: Schema.optional(Schema.Int),\n});\n\nexport type ElementState = typeof ElementState.Type;\n\n/** An element `find` found: a ref for the actions, what it is, where it is and its state. */\nexport class Found extends Schema.Class<Found>(\"effect-browser/Found\")({\n ref: Schema.String,\n subject: Subject,\n /** Its box, rounded. Reading the document, it may be out of view. */\n box: Box,\n inViewport: Schema.Boolean,\n state: ElementState,\n}) {}\n\nexport interface TextOptions {\n /** `\"viewport\"` (the default) reads what the viewport shows; a ref reads that element whole. */\n readonly scope?: string | undefined;\n /** Bound on the text's length, cut at a line. Defaults to 12,000 characters. */\n readonly maxChars?: number | undefined;\n /** Show what fields hold; a secret field still reads `••••`. Defaults to false. */\n readonly unmask?: boolean | undefined;\n}\n\n/** What a page showed as text: a line per block, with table cells apart by tabs. */\nexport class Text extends Schema.Class<Text>(\"effect-browser/Text\")({\n url: Schema.String,\n title: Schema.String,\n text: Schema.String,\n /** True when `text` was cut at `maxChars`. */\n truncated: Schema.Boolean,\n /** Host monotonic milliseconds from the browser's captured Effect Clock. */\n at: Schema.Finite,\n}) {}\n\n/** What `waitFor` waits for. */\nexport interface WaitCondition {\n /** A CSS selector for what to watch; the document's body without one. */\n readonly selector?: string | undefined;\n /**\n * `\"visible\"` (the default): something it matches shows; `\"hidden\"`: nothing it matches shows;\n * `\"enabled\"`: something it matches shows and is not disabled.\n */\n readonly state?: \"visible\" | \"hidden\" | \"enabled\" | undefined;\n /** Only what shows this text counts, case and all, with runs of spaces read as one. */\n readonly text?: string | undefined;\n}\n\nexport interface ReadyOptions {\n /** What must stay still during quietMillis: screen paint (default), or recorded content. */\n readonly still?: \"screen\" | \"content\" | undefined;\n /** How long the selected evidence must stay still; screen paint by default. */\n readonly quietMillis?: number | undefined;\n readonly timeout?: Duration.Input | undefined;\n}\n\n/** The window `changes` reads, and whether to show what fields hold. */\nexport interface ChangesOptions {\n /**\n * Where the window starts: the changes a previous read returned, to continue exactly where they\n * ended; a frame, at its paint; or host monotonic milliseconds, which mapped to the page's clock\n * may miss or repeat changes near the start if the browser's clock mapping changed since. Defaults\n * to the start of the record.\n */\n readonly since?: Changes | Frame | number | undefined;\n /**\n * Where it ends: a frame, at its paint, so a delayed frame's window holds nothing it does not\n * show; or host monotonic milliseconds. Defaults to now, and is never later.\n */\n readonly until?: Frame | number | undefined;\n /** Show what fields hold; a secret field still reads `••••`. Defaults to false. */\n readonly unmask?: boolean | undefined;\n}\n\n/** The window `window` reads, and whether to show what fields hold. */\nexport interface WindowOptions {\n /**\n * Where the window starts: a previous window, to continue exactly where it ended; a frame, at its\n * paint; host monotonic milliseconds; or a `Duration` back from `until`. A start after `until`\n * leaves the window empty there.\n */\n readonly since: Window | Frame | Duration.Duration | number;\n /**\n * Where it ends: a frame, at its paint, such as one a delayed consumer airs now; or host\n * monotonic milliseconds. Defaults to now, and is never later.\n */\n readonly until?: Frame | number | undefined;\n /** Show what fields hold in its changes; a secret field still reads `••••`. Defaults to false. */\n readonly unmask?: boolean | undefined;\n}\n\n/**\n * What the library knows of a page now, without asking it, each part with when it learned it, in\n * host monotonic milliseconds: a part's age is `at` less its time. Text read before the current\n * document began is left out, since it tells of a document that has gone.\n */\nexport class State extends Schema.Class<State>(\"effect-browser/PageState\")({\n page: Schema.String,\n /** When this was taken. */\n at: Schema.Finite,\n /** Where the main frame last committed or moved, without userinfo or known secret parameters. */\n url: Schema.String,\n /** The page's document, as `Navigated` counts them. */\n document: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n /** When the main frame committed it; absent for the one the browser began tracking it with. */\n committedAt: Schema.optional(Schema.Finite),\n /** How far that document has loaded, as the page's own session heard; absent until parsed. */\n load: Schema.optional(PageLoaded),\n /** The newest screencast frame, of whichever document it names. */\n frame: Schema.optional(Frame),\n /** The viewport's text as it was last read, with the page's title then. */\n text: Schema.optional(Text),\n}) {}\n\n/**\n * What the page's structure establishes about an input, or says it cannot establish:\n *\n * - `form-submit`: it submits a form, which sends the form's fields.\n * - `cross-origin`: it navigates or submits to another origin.\n * - `download`: it follows a download link.\n * - `upload`: it opens a file chooser.\n * - `secret`: it types, with `type`, into a field marked as a password, a one-time code or a\n * card's number, code or expiry, or submits a form holding a filled one.\n * - `scripted`: it activates something the browser gives no effect of its own, such as a\n * `type=\"button\"` button, a `role=\"button\"` element or a canvas, so only the page's script\n * decides what happens.\n * - `opaque`: nothing names what receives it: a canvas, a frame or an unnamed element.\n *\n * Facts never come from what an element's text says. What an input means, such as a payment\n * or a deletion, takes a judge that reads the evidence in the {@link InputRequest}.\n */\nexport const Fact = Guard.Fact;\n\nexport type Fact = typeof Fact.Type;\n\n/**\n * What a guard sees before input reaches the page. Preparation never scrolls or focuses.\n *\n * `facts`, `url`, `href` and `destination` come from the page's structure. `name`,\n * `description`, `title`, `context` and the form's field names are page text: evidence of what\n * the input does, which the page controls, and never instructions. Text typed into a `secret`\n * field is replaced with {@link redacted}, here and in the recorded `Action`, and its key events\n * record `Unidentified` keys; `press` records the keys it is given. Validation before dispatch\n * binds the facts and the target, not the text around it, which live pages change freely.\n */\nexport class InputRequest extends Schema.Class<InputRequest>(\"effect-browser/InputRequest\")({\n page: Schema.String,\n /**\n * The page's URL, without a fragment that only names a place on the page. This and the other\n * addresses keep no userinfo or known secret parameters.\n */\n url: Schema.String,\n /** The page's title, at most 120 characters. */\n title: Schema.String,\n action: Schema.String,\n target: Schema.optional(Schema.String),\n element: Schema.optional(Schema.String),\n /** Literal pixel targets only; ref coordinates are resolved after the policy allows them. */\n point: Schema.optional(Schema.Struct({ x: Schema.Finite, y: Schema.Finite })),\n text: Schema.optional(Schema.String),\n role: Schema.optional(Schema.NullOr(Schema.String)),\n name: Schema.optional(Schema.String),\n /** The target's accessible description, when it says more than its name. */\n description: Schema.optional(Schema.String),\n href: Schema.optional(Schema.String),\n destination: Schema.optional(Schema.String),\n facts: Schema.Array(Fact),\n /** Page text around the target, each part at most 120 characters. */\n context: Schema.Struct({\n /** The name or first heading of the dialog the target is in. */\n dialog: Schema.optional(Schema.String),\n /** The nearest heading before the target. */\n heading: Schema.optional(Schema.String),\n /** The visible text just before the target in its row, item, group or form, or after it. */\n nearby: Schema.optional(Schema.String),\n }),\n /** The form the target is in, with at most 16 of its fields. */\n form: Schema.optional(\n Schema.Struct({\n method: Schema.String,\n action: Schema.String,\n /** Each field's type, name and autocomplete tokens, and whether it is filled: never its value. */\n fields: Schema.Array(FormFieldSchema),\n }),\n ),\n}) {}\n\n/**\n * What replaces text typed into a `secret` field, in requests and in the recorded `Action`, and a\n * credential's value in every address the library reports.\n */\nexport const redacted = Url.withheld;\n\n/**\n * Run page operations without waiting their turn: on a page busy with other operations, each fails\n * `Busy` at once, and `Browser.newPage` on a browser with `maxPages` open fails `Limit` at once.\n */\nexport const failFast = <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n Effect.provideService(effect, FailFast, true);\n\n/**\n * Give every action `effect` performs a caller's id, such as a model's tool call id, which its\n * recorded `Action` carries as `correlation`.\n */\nexport const correlate =\n (id: string) =>\n <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n Effect.provideService(effect, Correlation, id);\n\n/** Succeed to allow, fail to deny, or await an external signal to hold the input. */\nexport type InputGuard = (request: InputRequest) => Effect.Effect<void, PolicyDenied>;\n\nexport interface Page {\n /** The page's CDP target id: the same page has it again after a reconnect to its browser. */\n readonly id: string;\n /** The Playwright page, for anything this API does not cover. Never give it to a model. */\n readonly playwright: PlaywrightPage;\n /** The page's address, without its userinfo or known secret parameters. */\n readonly url: Effect.Effect<string>;\n /**\n * The document's title as the page last set it, empty for an untitled page. The browser answers\n * it, in one call, so a page busy with a script cannot hold it up.\n */\n readonly title: Effect.Effect<string, BrowserError>;\n\n readonly goto: (url: string) => Effect.Effect<void, BrowserError>;\n /** The previous history entry, including one only a frame created; `NotFound` when none. */\n readonly back: Effect.Effect<void, BrowserError>;\n readonly reload: Effect.Effect<void, BrowserError>;\n /** Make this the visible tab. Background tabs paint rarely and send few screencast frames. */\n readonly bringToFront: Effect.Effect<void, BrowserError>;\n /** Close the tab, succeeding once it has closed, or at once when it already had. */\n readonly close: Effect.Effect<void, BrowserError>;\n\n readonly snapshot: (options?: SnapshotOptions) => Effect.Effect<Snapshot, BrowserError>;\n /**\n * A picture of the viewport, in CSS pixels: a screencast frame painted since the page's latest\n * input, if one qualifies, or a new one. A caller that has just acted sees what its action did.\n */\n readonly screenshot: (options?: ScreenshotOptions) => Effect.Effect<Image, BrowserError>;\n /**\n * The viewport with its timing: the newest screencast frame if it qualifies, else a new\n * screenshot timed by the host interval in which it was taken.\n */\n readonly frame: (options?: FrameOptions) => Effect.Effect<Frame, BrowserError>;\n /** A crop in CSS pixels, unmagnified, with the origin that keeps later input in viewport pixels. */\n readonly zoom: (region: Region) => Effect.Effect<Zoom, BrowserError>;\n /**\n * The viewport's size in CSS pixels, the space of points, crops and page scrolls. Over CDP the\n * page reports it, within the action timeout.\n */\n readonly viewport: Effect.Effect<\n { readonly width: number; readonly height: number },\n BrowserError\n >;\n /**\n * The elements that match a query, in tree order, with refs the actions take, in one call to the\n * page. All that match are returned, so a caller tells them apart by their context; none is an\n * empty result, not a failure.\n */\n readonly find: (query?: FindQuery) => Effect.Effect<ReadonlyArray<Found>, BrowserError>;\n /**\n * The text the viewport shows, or one element whole, in one call to the page. Field values read\n * `••••` unless `unmask`, and a secret field's always do, as does one that was secret when the\n * library saw it.\n */\n readonly text: (options?: TextOptions) => Effect.Effect<Text, BrowserError>;\n /**\n * What visibly changed over a window, in one call to the page. The first read starts the page's\n * record, so it finds none; from then the page records, and from the start of each later\n * document, until nobody has read it for two minutes. See `Change`.\n */\n readonly changes: (options?: ChangesOptions) => Effect.Effect<Changes, BrowserError>;\n /**\n * The page's events, changes and frames over a window: the frames and events it keeps, at no\n * call, and its changes, in one call, the first starting its record as `changes` does. A part\n * that cannot be read is missing, with why; the window fails only for bounds that are not finite.\n */\n readonly window: (options: WindowOptions) => Effect.Effect<Window, BrowserError>;\n /**\n * What the library knows of the page now, at no call and with no wait for its turn: where it is,\n * its document and how far it has loaded, its newest frame, and its text and title as last read.\n */\n readonly state: Effect.Effect<State>;\n\n readonly click: (\n target: Target,\n options?: ClickOptions,\n ) => Effect.Effect<ResolvedTarget, BrowserError>;\n readonly hover: (target: Target) => Effect.Effect<void, BrowserError>;\n readonly drag: (from: Target, to: Target) => Effect.Effect<void, BrowserError>;\n /** Type into a text field, or to whatever has focus unless a typed key could activate it. */\n readonly type: (text: string, options?: TypeOptions) => Effect.Effect<void, BrowserError>;\n /** Keys such as `\"Enter\"`, `\"Space\"`, `\"ArrowLeft\"` or `\"Control+A\"`. */\n readonly press: (keys: string, options?: PressOptions) => Effect.Effect<void, BrowserError>;\n readonly scroll: (options?: ScrollOptions) => Effect.Effect<void, BrowserError>;\n /**\n * Choose options of a `<select>` by value or label; returns the chosen labels. A refusal, such\n * as no matching option, is undispatched.\n */\n readonly select: (\n ref: string,\n values: ReadonlyArray<string>,\n ) => Effect.Effect<string, BrowserError>;\n\n /**\n * Wait until a condition holds, in one call that the page answers as it comes, looking every\n * 100 ms, or `Timeout` after `timeout`, 10 seconds by default. A selector that is not CSS is an\n * `InvalidRequest`.\n */\n readonly waitFor: (\n condition: WaitCondition,\n timeout?: Duration.Input,\n ) => Effect.Effect<void, BrowserError>;\n /**\n * Wait until the page is ready to be shown, asking the page every 100 ms: its document is parsed\n * and has painted since, nothing that ends is animating in view, its fonts and the images in\n * view have loaded, and the viewport shows something. With `quietMillis`, the screen must then\n * also stay still that long: nothing in view changed, where the page's changes are recorded, and\n * no frame comes, counted from the first frame of a capture the wait starts itself. A canvas\n * that keeps drawing, such as a live chart, is never still, and a page\n * is never ready without a painted frame, as a hidden tab may be. `Timeout` after `timeout`,\n * 15 seconds by default.\n */\n readonly ready: (options?: ReadyOptions) => Effect.Effect<void, BrowserError>;\n\n /**\n * Screencast frames for as long as the stream runs. Concurrent streams share one screencast and\n * its settings; explicit options that differ from a running screencast's fail with InvalidRequest.\n */\n readonly screencast: (options?: ScreencastOptions) => Stream.Stream<Frame, BrowserError>;\n /**\n * What this page's captures received, delivered and dropped, over its life or the latest\n * `window`, which reaches back at most a minute; a longer one is an `InvalidRequest`.\n */\n readonly captureStats: (options?: {\n readonly window?: Duration.Input | undefined;\n }) => Effect.Effect<CaptureStats, BrowserError>;\n /** Screencast frames painted within `frameHistory` of the newest, oldest first. */\n readonly recentFrames: Effect.Effect<ReadonlyArray<Frame>>;\n /** This page's events among the browser's latest `eventHistory`, oldest first. */\n readonly recentEvents: Effect.Effect<ReadonlyArray<BrowserEvent>>;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Plan-CXA2BW-G.mjs","names":[],"sources":["../src/internal/reading/choose.ts","../src/Plan.ts"],"sourcesContent":["/**\n * Choosing the one element a recorded subject names, among those `find` gives for its role and\n * name. Context tells them apart, and an element that does not repeat every part of the recorded\n * context is another subject, so a sole element left once its own has gone, such as Alice's\n * \"Remove\" after Bob has left, drifts rather than stands in:\n *\n * - a row is read whole: a row named \"Wrapped BTC\" is not the row \"BTC\". Laid out again without\n * rows, as cards, one of the element's fields must start with the row's words;\n * - a column counts where the element is under one;\n * - a label or heading must read the same, or its words appear, whole and in order, in one of the\n * element's fields, as `near` reads them.\n *\n * The rest are ranked by how much of the recorded context they read the same. There is no\n * ordinal, so a tie stays a tie.\n */\nimport { Effect, Schema } from \"effect\";\n\nimport type { Subject, SubjectContext } from \"../../BrowserEvent.ts\";\nimport type { Found } from \"../../Page.ts\";\nimport { match } from \"./match.inpage.ts\";\n\n/** Nothing on the page has the step's role and name. */\nexport class Missing extends Schema.TaggedError<Missing>()(\"Missing\", {}) {\n override get message() {\n return \"nothing on the page has the recorded role and name\";\n }\n}\n\n/** Several elements match the step's subject equally well, and nothing tells them apart. */\nexport class Ambiguous extends Schema.TaggedError<Ambiguous>()(\"Ambiguous\", {\n count: Schema.Int,\n}) {\n override get message() {\n return `${this.count} elements match the recorded subject equally well`;\n }\n}\n\n/** The page is not where the recording was: another site, or no element with its context. */\nexport class Drifted extends Schema.TaggedError<Drifted>()(\"Drifted\", {\n detail: Schema.String,\n}) {\n override get message() {\n return this.detail;\n }\n}\n\nconst { holds, normalize } = match();\nconst fields = [\"row\", \"column\", \"label\", \"heading\"] as const;\n\nconst said = (context: SubjectContext) =>\n Object.values(context).filter((value) => typeof value === \"string\");\n\n/** How an element repeats one recorded field: 2 read the same, 1 found as words, 0 not at all. */\nconst repeats = (field: (typeof fields)[number], value: string, context: SubjectContext) => {\n const own = context[field];\n\n if (own !== undefined && normalize(own) === normalize(value)) return 2;\n if (field === \"column\") return own === undefined ? 1 : 0;\n if (field === \"row\")\n return own === undefined &&\n said(context).some((other) => `${normalize(other)} `.startsWith(`${normalize(value)} `))\n ? 1\n : 0;\n\n return said(context).some((other) => holds(other, value)) ? 1 : 0;\n};\n\nexport const choose = (\n subject: Subject,\n found: ReadonlyArray<Found>,\n): Effect.Effect<Found, Missing | Ambiguous | Drifted> => {\n // `find` matched the role; a subject without one only matches elements without one.\n const named = found.filter((one) => subject.role !== null || one.subject.role === null);\n\n const kept = named.flatMap((one) => {\n let score = 0;\n\n for (const field of fields) {\n const value = subject.context[field];\n const repeated = value === undefined ? 0 : repeats(field, value, one.subject.context);\n\n if (value !== undefined && repeated === 0) return [];\n score += repeated;\n }\n\n return [{ one, score }];\n });\n\n const best = Math.max(...kept.map(({ score }) => score));\n const top = kept.filter(({ score }) => score === best);\n const [only] = top;\n\n if (named.length === 0) return Effect.fail(new Missing());\n if (kept.length === 0)\n return Effect.fail(new Drifted({ detail: \"no element named so repeats the recorded context\" }));\n\n return top.length === 1 && only !== undefined\n ? Effect.succeed(only.one)\n : Effect.fail(new Ambiguous({ count: top.length }));\n};\n","/**\n * A walk recorded once from a page's events and replayed later, on a fresh page, with no model\n * call.\n *\n * `fromEvents` keeps one page's completed actions with their subjects and the options they were\n * given, its navigations with both the address asked for and the one reached, and what was typed\n * as a named input slot, never the text itself. A navigation to an address whose credentials the\n * events withheld is an input slot too, so replay goes where the caller says, or nowhere, and\n * never to the address without them. `replay` takes the steps in turn. Before a step\n * except an opening navigate, back or reload, it waits for `Page.ready`; then it finds the element its\n * subject names, by role and name among those that repeat all its recorded context, and acts on\n * it. Text typed into focus was typed into the focused field, which replay finds the same way, and\n * text typed into a secret field goes into nothing else. An element step never falls back to\n * coordinates, and a step recorded at a point acts there only while the element found for it still\n * covers that point. `take` and `replay` return receipts; failure preserves a stopping point and\n * earlier receipts. Unknown consequential input is never resent. Only a positive durable read-back\n * can reconcile it; restoration follows the same rule. The consumer journals begun steps before\n * calling, treating interruption or a missing receipt as unknown. Plain recordings use version 1;\n * authored expected effects use version 2. Old 0.2 plans and unknown versions do not decode.\n *\n * @since 0.3.0\n */\nimport { Duration, Effect, Exit, Option, Schedule, Schema } from \"effect\";\n\nimport { BrowserError, InvalidRequest } from \"./BrowserError.ts\";\nimport {\n type Action,\n ActionOptions,\n Box,\n type BrowserEvent,\n type Navigated,\n Subject,\n} from \"./BrowserEvent.ts\";\nimport { undispatched } from \"./internal/page/context.ts\";\nimport { Ambiguous, choose, Drifted, Missing } from \"./internal/reading/choose.ts\";\nimport {\n type Found,\n type Page,\n type Point,\n type ReadyOptions,\n redacted,\n type Target,\n} from \"./Page.ts\";\n\nexport { Ambiguous, Drifted, Missing } from \"./internal/reading/choose.ts\";\n\nconst ViewportPoint = Schema.Struct({ x: Schema.Finite, y: Schema.Finite });\n\nexport const StepAction = Schema.Literals([\n \"navigate\",\n \"back\",\n \"reload\",\n \"click\",\n \"hover\",\n \"drag\",\n \"type\",\n \"press\",\n \"scroll\",\n \"select\",\n]);\n\nexport type StepAction = typeof StepAction.Type;\n\nconst Query = Schema.Struct({\n role: Schema.optional(Schema.String),\n name: Schema.optional(Schema.String),\n text: Schema.optional(Schema.String),\n});\n\n/**\n * What a step leaves. `durable` asserts an author-chosen, lasting read-back of this operation,\n * such as its uniquely named saved receipt or exact operation URL. Only Appeared and an exact\n * Navigated URL allow it; a toast, absence or relative navigation cannot establish recovery.\n * Relative navigation measures observed change from dispatch, without asserting causality.\n */\nexport const Expected = Schema.Union([\n Schema.TaggedStruct(\"Checked\", { checked: Schema.Boolean }),\n Schema.TaggedStruct(\"Appeared\", {\n query: Query,\n durable: Schema.optional(Schema.Literal(true)),\n }),\n Schema.TaggedStruct(\"Gone\", {\n query: Query,\n durable: Schema.optional(Schema.Never),\n }),\n Schema.TaggedStruct(\"Navigated\", {\n url: Schema.String,\n durable: Schema.optional(Schema.Literal(true)),\n }),\n Schema.TaggedStruct(\"Navigated\", {\n url: Schema.optional(Schema.Never),\n durable: Schema.optional(Schema.Never),\n }),\n]);\n\nexport type Expected = typeof Expected.Type;\n\n/** One recorded step: the action, what it acted on, and what else it was asked. */\nexport class Step extends Schema.Class<Step>(\"effect-browser/Plan/Step\")({\n action: StepAction,\n /**\n * The ending address, or a later recorded navigation before the next action began. Empty when\n * unknown; a delayed navigation can be stronger arrival evidence than the action's ending URL.\n */\n url: Schema.String,\n /** A navigation's requested address, or the keys a press pressed. */\n target: Schema.optional(Schema.String),\n subject: Schema.optional(Subject),\n /** Where a drag ended. */\n to: Schema.optional(Subject),\n /** The viewport point a step aimed at, when it aimed at a point, and a drag's end point. */\n point: Schema.optional(ViewportPoint),\n toPoint: Schema.optional(ViewportPoint),\n /** The box of what a step aimed at by point found there, so replay aims at the same place in it. */\n box: Schema.optional(Box),\n /**\n * The input slot whose text a `type` step types, or whose address a `navigate` step goes to, as\n * its recorded address had a credential withheld.\n */\n input: Schema.optional(Schema.String),\n /** The slot's text went into a secret field, so replay types it into nothing else. */\n secret: Schema.optional(Schema.Literal(true)),\n options: Schema.optional(ActionOptions),\n expect: Schema.optional(Expected),\n}) {}\n\nconst PlanData = Schema.Struct({\n version: Schema.Literals([1, 2]),\n steps: Schema.Array(Step),\n}).check(\n Schema.makeFilter((plan) =>\n plan.version === (plan.steps.some((step) => step.expect !== undefined) ? 2 : 1)\n ? undefined\n : \"only plans with expected effects use version 2\",\n ),\n);\n\nexport class Plan extends Schema.Class<Plan>(\"effect-browser/Plan\")(PlanData) {\n /** Choose the encoding version from the steps; simple recordings remain version 1. */\n static new(steps: ReadonlyArray<Step>): Plan {\n return new Plan({ version: steps.some((step) => step.expect !== undefined) ? 2 : 1, steps });\n }\n\n /** The input slots its steps type, in order; replay needs text for each. */\n get inputs(): ReadonlyArray<string> {\n return this.steps.flatMap((step) => (step.input === undefined ? [] : [step.input]));\n }\n}\n\n/** One completed step, on the page's host clock. `verified` means its expected effect was seen. */\nexport class Receipt extends Schema.Class<Receipt>(\"effect-browser/Plan/Receipt\")({\n step: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n outcome: Schema.Literals([\"taken\", \"verified\", \"skipped\"]),\n startedAt: Schema.Finite,\n at: Schema.Finite,\n}) {}\n\n/** Durable stopping data. A begun step without a receipt must be restored as `unknown`. */\nexport class Stopped extends Schema.Class<Stopped>(\"effect-browser/Plan/Stopped\")({\n step: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n input: Schema.Literals([\"unsent\", \"unknown\"]),\n}) {}\n\n/** Repeating this step could repeat an unresolved effect; the consumer must reconcile it. */\nexport class Uncertain extends Schema.TaggedError<Uncertain>()(\"Uncertain\", {\n detail: Schema.String,\n}) {\n override get message() {\n return this.detail;\n }\n}\n\n/** Where replay stopped, counting steps from 0, why, and the steps that completed before it. */\nexport class ReplayError extends Schema.TaggedError<ReplayError>()(\"ReplayError\", {\n step: Schema.Int,\n reason: Schema.Union([Missing, Ambiguous, Drifted, BrowserError, Uncertain]),\n input: Schema.Literals([\"unsent\", \"unknown\"]),\n receipts: Schema.Array(Receipt),\n}) {\n get stopped(): Stopped {\n return new Stopped({ step: this.step, input: this.input });\n }\n\n override get message() {\n return `step ${this.step} failed: ${this.reason.message}`;\n }\n}\n\nconst isStep = (event: BrowserEvent): event is Action & { readonly name: StepAction } =>\n event._tag === \"Action\" &&\n event.ok &&\n (StepAction.literals as ReadonlyArray<string>).includes(event.name);\n\n// A point target reads `x,y`, as `{\"x\":…,\"y\":…}` inside a drag's; a ref reads like e12.\nconst pointIn = (target: string | undefined): Point | undefined => {\n const parsed = /^\\{?(?:\"x\":)?(-?[\\d.]+),(?:\"y\":)?(-?[\\d.]+)\\}?$/.exec(target ?? \"\");\n\n return parsed === null ? undefined : { x: Number(parsed[1]), y: Number(parsed[2]) };\n};\n\n/** A slot named for the field it fills, such as `email`, unique within the plan. */\nconst slotFor = (taken: Set<string>, field: string | undefined) => {\n const base =\n field\n ?.toLowerCase()\n .match(/[\\p{L}\\p{N}]+/gu)\n ?.join(\"-\") ?? \"input\";\n\n let slot = base;\n\n for (let count = 2; taken.has(slot); count++) slot = `${base}-${count}`;\n taken.add(slot);\n\n return slot;\n};\n\n/**\n * The walk one page's events record: the completed actions of the page that acted first, in\n * order. `page.recentEvents` gives them, or `browser.events()` read until the walk ends.\n */\nexport const fromEvents = (events: Iterable<BrowserEvent>): Plan => {\n const all = Array.from(events);\n const page = all.find((event) => event._tag === \"Action\")?.page;\n const mine = all.filter((event) => \"page\" in event && event.page === page);\n const steps = mine.filter(isStep);\n const opened = mine.find((event) => event._tag === \"PageOpened\")?.url ?? \"\";\n const moves = mine.filter((event): event is Navigated => event._tag === \"Navigated\");\n const taken = new Set<string>();\n\n // Where the page was just before a time: the last address it reached by then.\n const before = (time: number) => moves.findLast((move) => move.at <= time)?.url ?? opened;\n\n return new Plan({\n version: 1,\n steps: steps.map((action, index) => {\n const drag = action.name === \"drag\" ? (action.target ?? \"\").split(\" -> \") : undefined;\n const point = pointIn(drag === undefined ? action.target : drag[0]);\n const until = steps[index + 1]?.startedAt ?? Number.POSITIVE_INFINITY;\n const arrival = moves.findLast((move) => move.at > action.at && move.at <= until);\n\n // Only a navigation and a press keep their target: an address, or keys.\n return new Step({\n action: action.name,\n url: arrival?.url ?? action.url ?? before(until),\n target: action.name === \"navigate\" || action.name === \"press\" ? action.target : undefined,\n subject: action.subject,\n to: action.to,\n point,\n toPoint: pointIn(drag?.[1]),\n box: point === undefined ? undefined : action.box,\n input:\n action.name === \"type\"\n ? slotFor(taken, action.subject?.name)\n : action.name === \"navigate\" && action.target?.includes(redacted) === true\n ? slotFor(taken, \"address\")\n : undefined,\n secret: action.name === \"type\" && action.text === redacted ? true : undefined,\n options: action.options,\n });\n }),\n });\n};\n\n/**\n * The one element on the page that a subject names, by role, name and context (see `Plan`),\n * looking again for two seconds while the page may still be drawing it.\n */\nexport const locate = (page: Page, subject: Subject) =>\n page\n .find({\n name: subject.name,\n scope: \"document\",\n ...(subject.role === null ? {} : { role: subject.role }),\n })\n .pipe(\n Effect.flatMap((found) => choose(subject, found)),\n Effect.retry({\n schedule: Schedule.spaced(Duration.millis(250)),\n times: 8,\n while: (error) => error._tag !== \"BrowserError\",\n }),\n Effect.withSpan(\"Plan.locate\", { attributes: { role: subject.role ?? \"\" } }),\n );\n\nconst invalid = (detail: string) => undispatched(\"replay\", new InvalidRequest({ detail }));\n\n/**\n * Where the step acts: the element its subject names, or, for a step recorded at a point, the same\n * place within that element, as long as a press there reaches that element and not one over it.\n * An element out of view is first brought into it, by hovering it, as a press by ref would be.\n */\nconst aim = (page: Page, subject: Subject | undefined, point?: Point, recorded?: Box) => {\n if (subject === undefined) return Effect.fail(invalid(\"the step names no element\"));\n if (point === undefined) return Effect.map(locate(page, subject), ({ ref }): Target => ref);\n\n const reach = ({ ref, box }: Found) => {\n const at =\n recorded === undefined || recorded.width <= 0 || recorded.height <= 0\n ? point\n : {\n x: box.x + ((point.x - recorded.x) / recorded.width) * box.width,\n y: box.y + ((point.y - recorded.y) / recorded.height) * box.height,\n };\n\n return Effect.map(page.find({ at }), ([reached]) => (reached?.ref === ref ? at : undefined));\n };\n\n const missed = new Drifted({ detail: \"a press at the subject's point reaches another element\" });\n\n return locate(page, subject).pipe(\n Effect.flatMap((found) =>\n Effect.flatMap(reach(found), (at) =>\n at !== undefined\n ? Effect.succeed<Target>(at)\n : page.hover(found.ref).pipe(\n Effect.andThen(locate(page, subject)),\n Effect.flatMap(reach),\n Effect.flatMap((again) =>\n again === undefined ? Effect.fail(missed) : Effect.succeed<Target>(again),\n ),\n ),\n ),\n ),\n );\n};\n\nconst dispatch = (\n page: Page,\n step: Step,\n text: string,\n): Effect.Effect<void, Missing | Ambiguous | Drifted | BrowserError> => {\n const options = step.options ?? {};\n\n switch (step.action) {\n case \"navigate\":\n return page.goto(step.input === undefined ? (step.target ?? step.url) : text);\n case \"back\":\n return page.back;\n case \"reload\":\n return page.reload;\n case \"press\":\n return step.subject === undefined\n ? page.press(step.target ?? \"\", options)\n : Effect.flatMap(locate(page, step.subject), ({ ref }) =>\n page.press(step.target ?? \"\", { ...options, on: ref }),\n );\n case \"click\":\n return aim(page, step.subject, step.point, step.box).pipe(\n Effect.flatMap((at) => page.click(at, options)),\n Effect.asVoid,\n );\n case \"hover\":\n return Effect.flatMap(aim(page, step.subject, step.point, step.box), page.hover);\n case \"drag\":\n return Effect.all([\n aim(page, step.subject, step.point),\n aim(page, step.to, step.toPoint),\n ]).pipe(Effect.flatMap(([from, to]) => page.drag(from, to)));\n case \"select\":\n return aim(page, step.subject).pipe(\n Effect.flatMap((at) => page.select(typeof at === \"string\" ? at : \"\", options.values ?? [])),\n Effect.asVoid,\n );\n // A scroll or a typing step may name no element: the page, or whatever has focus.\n case \"scroll\":\n return step.subject === undefined\n ? page.scroll(options)\n : Effect.flatMap(aim(page, step.subject, step.point, step.box), (at) =>\n page.scroll({ ...options, at }),\n );\n case \"type\":\n return step.subject === undefined\n ? page.type(text, { ...options, secret: step.secret })\n : Effect.flatMap(aim(page, step.subject), (into) =>\n page.type(text, {\n ...options,\n into: typeof into === \"string\" ? into : undefined,\n secret: step.secret,\n }),\n );\n }\n};\n\nexport interface TakeOptions {\n /** How each step waits first, except an opening navigation, or false. No final-step wait. */\n readonly settle?: ReadyOptions | false | undefined;\n readonly inputs?: Readonly<Record<string, string>> | undefined;\n /**\n * Bound for recorded arrival and expected effect, each. Defaults to 5 seconds. Zero makes one\n * read without polling; that read retains the page operation's timeout.\n */\n readonly arrival?: Duration.Input | undefined;\n}\n\nexport interface ReplayOptions extends TakeOptions {\n readonly from?: number | Stopped | undefined;\n}\n\n/**\n * Input that can be repeated without repeating a commitment. `take` also validates a Checked\n * target's boolean state before input. Back/reload can resubmit a form.\n */\nexport const repeatable = (step: Step): boolean =>\n [\"navigate\", \"hover\", \"scroll\", \"select\"].includes(step.action) ||\n (step.action === \"type\" &&\n step.subject !== undefined &&\n step.options?.replace !== false &&\n step.options?.submit !== true) ||\n (step.action === \"click\" && step.expect?._tag === \"Checked\");\n\ntype StepError = Missing | Ambiguous | Drifted | BrowserError | Uncertain;\n\n// Zero waits make one read; positive waits bound all reads and never repeat input.\nconst within = (check: Effect.Effect<boolean, StepError>, millis: number) =>\n millis === 0\n ? check\n : check.pipe(\n Effect.repeat({ until: (held) => held, schedule: Schedule.spaced(Duration.millis(25)) }),\n Effect.timeoutOrElse({\n duration: Duration.millis(millis),\n orElse: () => Effect.succeed(false),\n }),\n );\n\nconst sameSite = (url: string, recorded: string) => {\n const origin = URL.parse(recorded)?.origin;\n\n return (\n recorded === \"\" ||\n (origin === undefined || origin === \"null\"\n ? url === recorded\n : URL.parse(url)?.origin === origin)\n );\n};\n\nconst arrived = (page: Page, urls: ReadonlyArray<string>, millis: number) =>\n within(\n Effect.map(page.url, (url) => urls.some((recorded) => sameSite(url, recorded))),\n millis,\n ).pipe(\n Effect.filterOrFail(\n (held) => held,\n () =>\n new Drifted({ detail: \"the page did not reach the recorded site within the arrival wait\" }),\n ),\n Effect.asVoid,\n );\n\nconst checkEffect = (\n page: Page,\n step: Step,\n first?: { readonly url: string; readonly document: number },\n) => {\n const expected = step.expect;\n\n if (expected === undefined) return Effect.succeed(false);\n switch (expected._tag) {\n case \"Checked\":\n return step.subject === undefined\n ? Effect.fail(invalid(\"a checked effect needs a subject\"))\n : Effect.flatMap(locate(page, step.subject), (found) =>\n found.state.checked === undefined\n ? Effect.fail(invalid(\"a checked effect needs a checkable subject\"))\n : Effect.succeed(found.state.checked === expected.checked),\n );\n case \"Navigated\":\n if (expected.url === undefined && first === undefined) return Effect.succeed(false);\n\n return Effect.map(page.state, (now) =>\n expected.url === undefined\n ? now.url !== first?.url || now.document !== first?.document\n : now.url === expected.url,\n );\n case \"Appeared\":\n case \"Gone\":\n return Effect.map(page.find({ ...expected.query, scope: \"document\" }), (found) =>\n expected._tag === \"Appeared\" ? found.length > 0 : found.length === 0,\n );\n }\n};\n\n/**\n * Take one step. Unknown non-repeatable input is never resent: only positive durable read-back\n * can skip it. An interrupted call remains interrupted; persist begun-before-call in the consumer\n * and treat a missing receipt as Stopped{input: \"unknown\"}, including after process restart.\n */\nexport const take = Effect.fn(\"Plan.take\")(function* (\n page: Page,\n plan: Plan,\n at: number | Stopped,\n options: TakeOptions = {},\n): Effect.fn.Return<Receipt, ReplayError> {\n const index = typeof at === \"number\" ? at : at.step;\n let input: Stopped[\"input\"] = typeof at === \"number\" ? \"unsent\" : at.input;\n\n const work = Effect.gen(function* (): Effect.fn.Return<Receipt, StepError> {\n const step = plan.steps[index];\n\n if (!Number.isInteger(index) || index < 0 || step === undefined)\n return yield* invalid(\"the step index is outside the plan\");\n const duration = Duration.fromInput(options.arrival ?? Duration.seconds(5));\n\n if (\n Option.isNone(duration) ||\n Duration.isNegative(duration.value) ||\n !Duration.isFinite(duration.value)\n )\n return yield* invalid(\"arrival must be a finite nonnegative duration\");\n const millis = Duration.toMillis(duration.value);\n const first = yield* page.state;\n\n const uncertain = new Uncertain({\n detail: \"the step may have been sent; reconcile its durable effect before continuing\",\n });\n\n const unresolved = input === \"unknown\" && !repeatable(step);\n const expected = step.expect;\n\n const durable =\n expected !== undefined &&\n (expected._tag === \"Appeared\" ||\n (expected._tag === \"Navigated\" && typeof expected.url === \"string\")) &&\n expected.durable === true;\n\n if (\n !durable &&\n (unresolved || (expected !== undefined && \"durable\" in expected && expected.durable === true))\n )\n return yield* uncertain;\n if (\n options.settle !== false &&\n (index > 0 || ![\"navigate\", \"back\", \"reload\"].includes(step.action))\n )\n yield* page.ready(options.settle);\n const before = plan.steps[index - 1]?.url;\n\n if (before !== undefined)\n yield* arrived(page, unresolved ? [before, step.url] : [before], millis);\n const check = checkEffect(page, step);\n\n const read =\n millis === 0\n ? check\n : check.pipe(\n Effect.timeoutOrElse({\n duration: Duration.millis(millis),\n orElse: () =>\n Effect.fail(new Drifted({ detail: \"the expected-effect read timed out\" })),\n }),\n );\n\n const held = yield* read.pipe(Effect.mapError((error) => (unresolved ? uncertain : error)));\n\n const receipt = (outcome: Receipt[\"outcome\"]) =>\n Effect.gen(function* () {\n yield* arrived(page, [step.url], millis);\n const now = yield* page.state;\n\n return new Receipt({ step: index, outcome, startedAt: first.at, at: now.at });\n });\n\n if (held) return yield* receipt(\"skipped\");\n if (unresolved) return yield* uncertain;\n const text = step.input === undefined ? \"\" : options.inputs?.[step.input];\n\n if (text === undefined) return yield* invalid(`no text for the input \"${step.input ?? \"\"}\"`);\n const verify = checkEffect(page, step, yield* page.state);\n const acted = yield* Effect.exit(dispatch(page, step, text));\n\n if (Exit.isFailure(acted)) {\n const error = Exit.findErrorOption(acted);\n\n if (Option.isSome(error) && error.value._tag === \"BrowserError\" && error.value.dispatched) {\n input = \"unknown\";\n if (expected !== undefined && (repeatable(step) || durable)) {\n const observed = yield* Effect.exit(within(verify, millis));\n\n if (Exit.isSuccess(observed) && observed.value) return yield* receipt(\"verified\");\n }\n }\n\n return yield* Effect.failCause(acted.cause);\n }\n input = \"unknown\";\n if (expected !== undefined && !(yield* within(verify, millis)))\n return yield* new Drifted({ detail: \"the step's expected effect did not arrive\" });\n\n return yield* receipt(expected === undefined ? \"taken\" : \"verified\");\n });\n\n return yield* work.pipe(\n Effect.mapError(\n (reason) =>\n new ReplayError({\n step: index,\n reason,\n input,\n receipts: [],\n }),\n ),\n );\n});\n\nconst run = Effect.fnUntraced(function* (\n page: Page,\n plan: Plan,\n options: TakeOptions,\n from: number | Stopped,\n until: number,\n restoring: boolean,\n) {\n const receipts: Array<Receipt> = [];\n const start = typeof from === \"number\" ? from : from.step;\n\n if (\n !Number.isInteger(start) ||\n start < 0 ||\n start > plan.steps.length ||\n !Number.isInteger(until) ||\n until < start ||\n until > plan.steps.length\n )\n return yield* new ReplayError({\n step: start,\n input: \"unsent\",\n receipts,\n reason: invalid(\"the run bounds are outside the plan\"),\n });\n // Fresh runs still ask for all input slots before changing the page. Restoration checks first.\n if (!restoring && typeof from === \"number\") {\n const unfilled = plan.steps.findIndex(\n (step, index) =>\n index >= start && step.input !== undefined && options.inputs?.[step.input] === undefined,\n );\n\n if (unfilled !== -1)\n return yield* new ReplayError({\n step: start,\n input: \"unsent\",\n receipts,\n reason: invalid(`no text for the input \"${plan.steps[unfilled]?.input ?? \"\"}\"`),\n });\n }\n for (let index = start; index < until; index++) {\n const at = restoring\n ? new Stopped({ step: index, input: \"unknown\" })\n : index === start\n ? from\n : index;\n\n const receipt = yield* take(page, plan, at, options).pipe(\n Effect.mapError((error) => new ReplayError({ ...error, receipts: [...receipts] })),\n );\n\n receipts.push(receipt);\n }\n\n return receipts;\n});\n\n/** Take a plan's steps from a fresh index or durable stopping point, returning completed receipts. */\nexport const replay = (page: Page, plan: Plan, options: ReplayOptions = {}) =>\n run(page, plan, options, options.from ?? 0, plan.steps.length, false).pipe(\n Effect.withSpan(\"Plan.replay\"),\n );\n\n/** Restore prior steps on a fresh page; unresolved commitments require positive durable evidence. */\nexport const restore = (\n page: Page,\n plan: Plan,\n options: TakeOptions & { readonly upTo?: number | undefined } = {},\n) =>\n run(page, plan, options, 0, options.upTo ?? plan.steps.length, true).pipe(\n Effect.withSpan(\"Plan.restore\"),\n );\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAsBA,IAAa,UAAb,cAA6B,OAAO,YAAqB,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CACxE,IAAa,UAAU;EACrB,OAAO;CACT;AACF;;AAGA,IAAa,YAAb,cAA+B,OAAO,YAAuB,CAAC,CAAC,aAAa,EAC1E,OAAO,OAAO,IAChB,CAAC,CAAC,CAAC;CACD,IAAa,UAAU;EACrB,OAAO,GAAG,KAAK,MAAM;CACvB;AACF;;AAGA,IAAa,UAAb,cAA6B,OAAO,YAAqB,CAAC,CAAC,WAAW,EACpE,QAAQ,OAAO,OACjB,CAAC,CAAC,CAAC;CACD,IAAa,UAAU;EACrB,OAAO,KAAK;CACd;AACF;AAEA,MAAM,EAAE,OAAO,cAAc,MAAM;AACnC,MAAM,SAAS;CAAC;CAAO;CAAU;CAAS;AAAS;AAEnD,MAAM,QAAQ,YACZ,OAAO,OAAO,OAAO,CAAC,CAAC,QAAQ,UAAU,OAAO,UAAU,QAAQ;;AAGpE,MAAM,WAAW,OAAgC,OAAe,YAA4B;CAC1F,MAAM,MAAM,QAAQ;CAEpB,IAAI,QAAQ,KAAA,KAAa,UAAU,GAAG,MAAM,UAAU,KAAK,GAAG,OAAO;CACrE,IAAI,UAAU,UAAU,OAAO,QAAQ,KAAA,IAAY,IAAI;CACvD,IAAI,UAAU,OACZ,OAAO,QAAQ,KAAA,KACb,KAAK,OAAO,CAAC,CAAC,MAAM,UAAU,GAAG,UAAU,KAAK,EAAE,GAAG,WAAW,GAAG,UAAU,KAAK,EAAE,EAAE,CAAC,IACrF,IACA;CAEN,OAAO,KAAK,OAAO,CAAC,CAAC,MAAM,UAAU,MAAM,OAAO,KAAK,CAAC,IAAI,IAAI;AAClE;AAEA,MAAa,UACX,SACA,UACwD;CAExD,MAAM,QAAQ,MAAM,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,IAAI,QAAQ,SAAS,IAAI;CAEtF,MAAM,OAAO,MAAM,SAAS,QAAQ;EAClC,IAAI,QAAQ;EAEZ,KAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,QAAQ,QAAQ,QAAQ;GAC9B,MAAM,WAAW,UAAU,KAAA,IAAY,IAAI,QAAQ,OAAO,OAAO,IAAI,QAAQ,OAAO;GAEpF,IAAI,UAAU,KAAA,KAAa,aAAa,GAAG,OAAO,CAAC;GACnD,SAAS;EACX;EAEA,OAAO,CAAC;GAAE;GAAK;EAAM,CAAC;CACxB,CAAC;CAED,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,KAAK,EAAE,YAAY,KAAK,CAAC;CACvD,MAAM,MAAM,KAAK,QAAQ,EAAE,YAAY,UAAU,IAAI;CACrD,MAAM,CAAC,QAAQ;CAEf,IAAI,MAAM,WAAW,GAAG,OAAO,OAAO,KAAK,IAAI,QAAQ,CAAC;CACxD,IAAI,KAAK,WAAW,GAClB,OAAO,OAAO,KAAK,IAAI,QAAQ,EAAE,QAAQ,mDAAmD,CAAC,CAAC;CAEhG,OAAO,IAAI,WAAW,KAAK,SAAS,KAAA,IAChC,OAAO,QAAQ,KAAK,GAAG,IACvB,OAAO,KAAK,IAAI,UAAU,EAAE,OAAO,IAAI,OAAO,CAAC,CAAC;AACtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrDA,MAAM,gBAAgB,OAAO,OAAO;CAAE,GAAG,OAAO;CAAQ,GAAG,OAAO;AAAO,CAAC;AAE1E,MAAa,aAAa,OAAO,SAAS;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAID,MAAM,QAAQ,OAAO,OAAO;CAC1B,MAAM,OAAO,SAAS,OAAO,MAAM;CACnC,MAAM,OAAO,SAAS,OAAO,MAAM;CACnC,MAAM,OAAO,SAAS,OAAO,MAAM;AACrC,CAAC;;;;;;;AAQD,MAAa,WAAW,OAAO,MAAM;CACnC,OAAO,aAAa,WAAW,EAAE,SAAS,OAAO,QAAQ,CAAC;CAC1D,OAAO,aAAa,YAAY;EAC9B,OAAO;EACP,SAAS,OAAO,SAAS,OAAO,QAAQ,IAAI,CAAC;CAC/C,CAAC;CACD,OAAO,aAAa,QAAQ;EAC1B,OAAO;EACP,SAAS,OAAO,SAAS,OAAO,KAAK;CACvC,CAAC;CACD,OAAO,aAAa,aAAa;EAC/B,KAAK,OAAO;EACZ,SAAS,OAAO,SAAS,OAAO,QAAQ,IAAI,CAAC;CAC/C,CAAC;CACD,OAAO,aAAa,aAAa;EAC/B,KAAK,OAAO,SAAS,OAAO,KAAK;EACjC,SAAS,OAAO,SAAS,OAAO,KAAK;CACvC,CAAC;AACH,CAAC;;AAKD,IAAa,OAAb,cAA0B,OAAO,MAAY,0BAA0B,CAAC,CAAC;CACvE,QAAQ;;;;;CAKR,KAAK,OAAO;;CAEZ,QAAQ,OAAO,SAAS,OAAO,MAAM;CACrC,SAAS,OAAO,SAAS,OAAO;;CAEhC,IAAI,OAAO,SAAS,OAAO;;CAE3B,OAAO,OAAO,SAAS,aAAa;CACpC,SAAS,OAAO,SAAS,aAAa;;CAEtC,KAAK,OAAO,SAAS,GAAG;;;;;CAKxB,OAAO,OAAO,SAAS,OAAO,MAAM;;CAEpC,QAAQ,OAAO,SAAS,OAAO,QAAQ,IAAI,CAAC;CAC5C,SAAS,OAAO,SAAS,aAAa;CACtC,QAAQ,OAAO,SAAS,QAAQ;AAClC,CAAC,CAAC,CAAC,CAAC;AAEJ,MAAM,WAAW,OAAO,OAAO;CAC7B,SAAS,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;CAC/B,OAAO,OAAO,MAAM,IAAI;AAC1B,CAAC,CAAC,CAAC,MACD,OAAO,YAAY,SACjB,KAAK,aAAa,KAAK,MAAM,MAAM,SAAS,KAAK,WAAW,KAAA,CAAS,IAAI,IAAI,KACzE,KAAA,IACA,gDACN,CACF;AAEA,IAAa,OAAb,MAAa,aAAa,OAAO,MAAY,qBAAqB,CAAC,CAAC,QAAQ,CAAC,CAAC;;CAE5E,OAAO,IAAI,OAAkC;EAC3C,OAAO,IAAI,KAAK;GAAE,SAAS,MAAM,MAAM,SAAS,KAAK,WAAW,KAAA,CAAS,IAAI,IAAI;GAAG;EAAM,CAAC;CAC7F;;CAGA,IAAI,SAAgC;EAClC,OAAO,KAAK,MAAM,SAAS,SAAU,KAAK,UAAU,KAAA,IAAY,CAAC,IAAI,CAAC,KAAK,KAAK,CAAE;CACpF;AACF;;AAGA,IAAa,UAAb,cAA6B,OAAO,MAAe,6BAA6B,CAAC,CAAC;CAChF,MAAM,OAAO,IAAI,MAAM,OAAO,uBAAuB,CAAC,CAAC;CACvD,SAAS,OAAO,SAAS;EAAC;EAAS;EAAY;CAAS,CAAC;CACzD,WAAW,OAAO;CAClB,IAAI,OAAO;AACb,CAAC,CAAC,CAAC,CAAC;;AAGJ,IAAa,UAAb,cAA6B,OAAO,MAAe,6BAA6B,CAAC,CAAC;CAChF,MAAM,OAAO,IAAI,MAAM,OAAO,uBAAuB,CAAC,CAAC;CACvD,OAAO,OAAO,SAAS,CAAC,UAAU,SAAS,CAAC;AAC9C,CAAC,CAAC,CAAC,CAAC;;AAGJ,IAAa,YAAb,cAA+B,OAAO,YAAuB,CAAC,CAAC,aAAa,EAC1E,QAAQ,OAAO,OACjB,CAAC,CAAC,CAAC;CACD,IAAa,UAAU;EACrB,OAAO,KAAK;CACd;AACF;;AAGA,IAAa,cAAb,cAAiC,OAAO,YAAyB,CAAC,CAAC,eAAe;CAChF,MAAM,OAAO;CACb,QAAQ,OAAO,MAAM;EAAC;EAAS;EAAW;EAAS;EAAc;CAAS,CAAC;CAC3E,OAAO,OAAO,SAAS,CAAC,UAAU,SAAS,CAAC;CAC5C,UAAU,OAAO,MAAM,OAAO;AAChC,CAAC,CAAC,CAAC;CACD,IAAI,UAAmB;EACrB,OAAO,IAAI,QAAQ;GAAE,MAAM,KAAK;GAAM,OAAO,KAAK;EAAM,CAAC;CAC3D;CAEA,IAAa,UAAU;EACrB,OAAO,QAAQ,KAAK,KAAK,WAAW,KAAK,OAAO;CAClD;AACF;AAEA,MAAM,UAAU,UACd,MAAM,SAAS,YACf,MAAM,MACL,WAAW,SAAmC,SAAS,MAAM,IAAI;AAGpE,MAAM,WAAW,WAAkD;CACjE,MAAM,SAAS,kDAAkD,KAAK,UAAU,EAAE;CAElF,OAAO,WAAW,OAAO,KAAA,IAAY;EAAE,GAAG,OAAO,OAAO,EAAE;EAAG,GAAG,OAAO,OAAO,EAAE;CAAE;AACpF;;AAGA,MAAM,WAAW,OAAoB,UAA8B;CACjE,MAAM,OACJ,OACI,YAAY,CAAC,CACd,MAAM,iBAAiB,CAAC,EACvB,KAAK,GAAG,KAAK;CAEnB,IAAI,OAAO;CAEX,KAAK,IAAI,QAAQ,GAAG,MAAM,IAAI,IAAI,GAAG,SAAS,OAAO,GAAG,KAAK,GAAG;CAChE,MAAM,IAAI,IAAI;CAEd,OAAO;AACT;;;;;AAMA,MAAa,cAAc,WAAyC;CAClE,MAAM,MAAM,MAAM,KAAK,MAAM;CAC7B,MAAM,OAAO,IAAI,MAAM,UAAU,MAAM,SAAS,QAAQ,CAAC,EAAE;CAC3D,MAAM,OAAO,IAAI,QAAQ,UAAU,UAAU,SAAS,MAAM,SAAS,IAAI;CACzE,MAAM,QAAQ,KAAK,OAAO,MAAM;CAChC,MAAM,SAAS,KAAK,MAAM,UAAU,MAAM,SAAS,YAAY,CAAC,EAAE,OAAO;CACzE,MAAM,QAAQ,KAAK,QAAQ,UAA8B,MAAM,SAAS,WAAW;CACnF,MAAM,wBAAQ,IAAI,IAAY;CAG9B,MAAM,UAAU,SAAiB,MAAM,UAAU,SAAS,KAAK,MAAM,IAAI,CAAC,EAAE,OAAO;CAEnF,OAAO,IAAI,KAAK;EACd,SAAS;EACT,OAAO,MAAM,KAAK,QAAQ,UAAU;GAClC,MAAM,OAAO,OAAO,SAAS,UAAU,OAAO,UAAU,GAAA,CAAI,MAAM,MAAM,IAAI,KAAA;GAC5E,MAAM,QAAQ,QAAQ,SAAS,KAAA,IAAY,OAAO,SAAS,KAAK,EAAE;GAClE,MAAM,QAAQ,MAAM,QAAQ,EAAE,EAAE,aAAa,OAAO;GACpD,MAAM,UAAU,MAAM,UAAU,SAAS,KAAK,KAAK,OAAO,MAAM,KAAK,MAAM,KAAK;GAGhF,OAAO,IAAI,KAAK;IACd,QAAQ,OAAO;IACf,KAAK,SAAS,OAAO,OAAO,OAAO,OAAO,KAAK;IAC/C,QAAQ,OAAO,SAAS,cAAc,OAAO,SAAS,UAAU,OAAO,SAAS,KAAA;IAChF,SAAS,OAAO;IAChB,IAAI,OAAO;IACX;IACA,SAAS,QAAQ,OAAO,EAAE;IAC1B,KAAK,UAAU,KAAA,IAAY,KAAA,IAAY,OAAO;IAC9C,OACE,OAAO,SAAS,SACZ,QAAQ,OAAO,OAAO,SAAS,IAAI,IACnC,OAAO,SAAS,cAAc,OAAO,QAAQ,SAAS,QAAQ,MAAM,OAClE,QAAQ,OAAO,SAAS,IACxB,KAAA;IACR,QAAQ,OAAO,SAAS,UAAU,OAAO,SAAS,WAAW,OAAO,KAAA;IACpE,SAAS,OAAO;GAClB,CAAC;EACH,CAAC;CACH,CAAC;AACH;;;;;AAMA,MAAa,UAAU,MAAY,YACjC,KACG,KAAK;CACJ,MAAM,QAAQ;CACd,OAAO;CACP,GAAI,QAAQ,SAAS,OAAO,CAAC,IAAI,EAAE,MAAM,QAAQ,KAAK;AACxD,CAAC,CAAC,CACD,KACC,OAAO,SAAS,UAAU,OAAO,SAAS,KAAK,CAAC,GAChD,OAAO,MAAM;CACX,UAAU,SAAS,OAAO,SAAS,OAAO,GAAG,CAAC;CAC9C,OAAO;CACP,QAAQ,UAAU,MAAM,SAAS;AACnC,CAAC,GACD,OAAO,SAAS,eAAe,EAAE,YAAY,EAAE,MAAM,QAAQ,QAAQ,GAAG,EAAE,CAAC,CAC7E;AAEJ,MAAM,WAAW,WAAmB,aAAa,UAAU,IAAI,eAAe,EAAE,OAAO,CAAC,CAAC;;;;;;AAOzF,MAAM,OAAO,MAAY,SAA8B,OAAe,aAAmB;CACvF,IAAI,YAAY,KAAA,GAAW,OAAO,OAAO,KAAK,QAAQ,2BAA2B,CAAC;CAClF,IAAI,UAAU,KAAA,GAAW,OAAO,OAAO,IAAI,OAAO,MAAM,OAAO,IAAI,EAAE,UAAkB,GAAG;CAE1F,MAAM,SAAS,EAAE,KAAK,UAAiB;EACrC,MAAM,KACJ,aAAa,KAAA,KAAa,SAAS,SAAS,KAAK,SAAS,UAAU,IAChE,QACA;GACE,GAAG,IAAI,KAAM,MAAM,IAAI,SAAS,KAAK,SAAS,QAAS,IAAI;GAC3D,GAAG,IAAI,KAAM,MAAM,IAAI,SAAS,KAAK,SAAS,SAAU,IAAI;EAC9D;EAEN,OAAO,OAAO,IAAI,KAAK,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,aAAc,SAAS,QAAQ,MAAM,KAAK,KAAA,CAAU;CAC7F;CAEA,MAAM,SAAS,IAAI,QAAQ,EAAE,QAAQ,yDAAyD,CAAC;CAE/F,OAAO,OAAO,MAAM,OAAO,CAAC,CAAC,KAC3B,OAAO,SAAS,UACd,OAAO,QAAQ,MAAM,KAAK,IAAI,OAC5B,OAAO,KAAA,IACH,OAAO,QAAgB,EAAE,IACzB,KAAK,MAAM,MAAM,GAAG,CAAC,CAAC,KACpB,OAAO,QAAQ,OAAO,MAAM,OAAO,CAAC,GACpC,OAAO,QAAQ,KAAK,GACpB,OAAO,SAAS,UACd,UAAU,KAAA,IAAY,OAAO,KAAK,MAAM,IAAI,OAAO,QAAgB,KAAK,CAC1E,CACF,CACN,CACF,CACF;AACF;AAEA,MAAM,YACJ,MACA,MACA,SACsE;CACtE,MAAM,UAAU,KAAK,WAAW,CAAC;CAEjC,QAAQ,KAAK,QAAb;EACE,KAAK,YACH,OAAO,KAAK,KAAK,KAAK,UAAU,KAAA,IAAa,KAAK,UAAU,KAAK,MAAO,IAAI;EAC9E,KAAK,QACH,OAAO,KAAK;EACd,KAAK,UACH,OAAO,KAAK;EACd,KAAK,SACH,OAAO,KAAK,YAAY,KAAA,IACpB,KAAK,MAAM,KAAK,UAAU,IAAI,OAAO,IACrC,OAAO,QAAQ,OAAO,MAAM,KAAK,OAAO,IAAI,EAAE,UAC5C,KAAK,MAAM,KAAK,UAAU,IAAI;GAAE,GAAG;GAAS,IAAI;EAAI,CAAC,CACvD;EACN,KAAK,SACH,OAAO,IAAI,MAAM,KAAK,SAAS,KAAK,OAAO,KAAK,GAAG,CAAC,CAAC,KACnD,OAAO,SAAS,OAAO,KAAK,MAAM,IAAI,OAAO,CAAC,GAC9C,OAAO,MACT;EACF,KAAK,SACH,OAAO,OAAO,QAAQ,IAAI,MAAM,KAAK,SAAS,KAAK,OAAO,KAAK,GAAG,GAAG,KAAK,KAAK;EACjF,KAAK,QACH,OAAO,OAAO,IAAI,CAChB,IAAI,MAAM,KAAK,SAAS,KAAK,KAAK,GAClC,IAAI,MAAM,KAAK,IAAI,KAAK,OAAO,CACjC,CAAC,CAAC,CAAC,KAAK,OAAO,SAAS,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,EAAE,CAAC,CAAC;EAC7D,KAAK,UACH,OAAO,IAAI,MAAM,KAAK,OAAO,CAAC,CAAC,KAC7B,OAAO,SAAS,OAAO,KAAK,OAAO,OAAO,OAAO,WAAW,KAAK,IAAI,QAAQ,UAAU,CAAC,CAAC,CAAC,GAC1F,OAAO,MACT;EAEF,KAAK,UACH,OAAO,KAAK,YAAY,KAAA,IACpB,KAAK,OAAO,OAAO,IACnB,OAAO,QAAQ,IAAI,MAAM,KAAK,SAAS,KAAK,OAAO,KAAK,GAAG,IAAI,OAC7D,KAAK,OAAO;GAAE,GAAG;GAAS;EAAG,CAAC,CAChC;EACN,KAAK,QACH,OAAO,KAAK,YAAY,KAAA,IACpB,KAAK,KAAK,MAAM;GAAE,GAAG;GAAS,QAAQ,KAAK;EAAO,CAAC,IACnD,OAAO,QAAQ,IAAI,MAAM,KAAK,OAAO,IAAI,SACvC,KAAK,KAAK,MAAM;GACd,GAAG;GACH,MAAM,OAAO,SAAS,WAAW,OAAO,KAAA;GACxC,QAAQ,KAAK;EACf,CAAC,CACH;CACR;AACF;;;;;AAqBA,MAAa,cAAc,SACzB;CAAC;CAAY;CAAS;CAAU;AAAQ,CAAC,CAAC,SAAS,KAAK,MAAM,KAC7D,KAAK,WAAW,UACf,KAAK,YAAY,KAAA,KACjB,KAAK,SAAS,YAAY,SAC1B,KAAK,SAAS,WAAW,QAC1B,KAAK,WAAW,WAAW,KAAK,QAAQ,SAAS;AAKpD,MAAM,UAAU,OAA0C,WACxD,WAAW,IACP,QACA,MAAM,KACJ,OAAO,OAAO;CAAE,QAAQ,SAAS;CAAM,UAAU,SAAS,OAAO,SAAS,OAAO,EAAE,CAAC;AAAE,CAAC,GACvF,OAAO,cAAc;CACnB,UAAU,SAAS,OAAO,MAAM;CAChC,cAAc,OAAO,QAAQ,KAAK;AACpC,CAAC,CACH;AAEN,MAAM,YAAY,KAAa,aAAqB;CAClD,MAAM,SAAS,IAAI,MAAM,QAAQ,CAAC,EAAE;CAEpC,OACE,aAAa,OACZ,WAAW,KAAA,KAAa,WAAW,SAChC,QAAQ,WACR,IAAI,MAAM,GAAG,CAAC,EAAE,WAAW;AAEnC;AAEA,MAAM,WAAW,MAAY,MAA6B,WACxD,OACE,OAAO,IAAI,KAAK,MAAM,QAAQ,KAAK,MAAM,aAAa,SAAS,KAAK,QAAQ,CAAC,CAAC,GAC9E,MACF,CAAC,CAAC,KACA,OAAO,cACJ,SAAS,YAER,IAAI,QAAQ,EAAE,QAAQ,mEAAmE,CAAC,CAC9F,GACA,OAAO,MACT;AAEF,MAAM,eACJ,MACA,MACA,UACG;CACH,MAAM,WAAW,KAAK;CAEtB,IAAI,aAAa,KAAA,GAAW,OAAO,OAAO,QAAQ,KAAK;CACvD,QAAQ,SAAS,MAAjB;EACE,KAAK,WACH,OAAO,KAAK,YAAY,KAAA,IACpB,OAAO,KAAK,QAAQ,kCAAkC,CAAC,IACvD,OAAO,QAAQ,OAAO,MAAM,KAAK,OAAO,IAAI,UAC1C,MAAM,MAAM,YAAY,KAAA,IACpB,OAAO,KAAK,QAAQ,4CAA4C,CAAC,IACjE,OAAO,QAAQ,MAAM,MAAM,YAAY,SAAS,OAAO,CAC7D;EACN,KAAK;GACH,IAAI,SAAS,QAAQ,KAAA,KAAa,UAAU,KAAA,GAAW,OAAO,OAAO,QAAQ,KAAK;GAElF,OAAO,OAAO,IAAI,KAAK,QAAQ,QAC7B,SAAS,QAAQ,KAAA,IACb,IAAI,QAAQ,OAAO,OAAO,IAAI,aAAa,OAAO,WAClD,IAAI,QAAQ,SAAS,GAC3B;EACF,KAAK;EACL,KAAK,QACH,OAAO,OAAO,IAAI,KAAK,KAAK;GAAE,GAAG,SAAS;GAAO,OAAO;EAAW,CAAC,IAAI,UACtE,SAAS,SAAS,aAAa,MAAM,SAAS,IAAI,MAAM,WAAW,CACrE;CACJ;AACF;;;;;;AAOA,MAAa,OAAO,OAAO,GAAG,WAAW,CAAC,CAAC,WACzC,MACA,MACA,IACA,UAAuB,CAAC,GACgB;CACxC,MAAM,QAAQ,OAAO,OAAO,WAAW,KAAK,GAAG;CAC/C,IAAI,QAA0B,OAAO,OAAO,WAAW,WAAW,GAAG;CAiGrE,OAAO,OA/FM,OAAO,IAAI,aAAmD;EACzE,MAAM,OAAO,KAAK,MAAM;EAExB,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,SAAS,KAAA,GACpD,OAAO,OAAO,QAAQ,oCAAoC;EAC5D,MAAM,WAAW,SAAS,UAAU,QAAQ,WAAW,SAAS,QAAQ,CAAC,CAAC;EAE1E,IACE,OAAO,OAAO,QAAQ,KACtB,SAAS,WAAW,SAAS,KAAK,KAClC,CAAC,SAAS,SAAS,SAAS,KAAK,GAEjC,OAAO,OAAO,QAAQ,+CAA+C;EACvE,MAAM,SAAS,SAAS,SAAS,SAAS,KAAK;EAC/C,MAAM,QAAQ,OAAO,KAAK;EAE1B,MAAM,YAAY,IAAI,UAAU,EAC9B,QAAQ,8EACV,CAAC;EAED,MAAM,aAAa,UAAU,aAAa,CAAC,WAAW,IAAI;EAC1D,MAAM,WAAW,KAAK;EAEtB,MAAM,UACJ,aAAa,KAAA,MACZ,SAAS,SAAS,cAChB,SAAS,SAAS,eAAe,OAAO,SAAS,QAAQ,aAC5D,SAAS,YAAY;EAEvB,IACE,CAAC,YACA,cAAe,aAAa,KAAA,KAAa,aAAa,YAAY,SAAS,YAAY,OAExF,OAAO,OAAO;EAChB,IACE,QAAQ,WAAW,UAClB,QAAQ,KAAK,CAAC;GAAC;GAAY;GAAQ;EAAQ,CAAC,CAAC,SAAS,KAAK,MAAM,IAElE,OAAO,KAAK,MAAM,QAAQ,MAAM;EAClC,MAAM,SAAS,KAAK,MAAM,QAAQ,EAAE,EAAE;EAEtC,IAAI,WAAW,KAAA,GACb,OAAO,QAAQ,MAAM,aAAa,CAAC,QAAQ,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM;EACzE,MAAM,QAAQ,YAAY,MAAM,IAAI;EAapC,MAAM,OAAO,QAVX,WAAW,IACP,QACA,MAAM,KACJ,OAAO,cAAc;GACnB,UAAU,SAAS,OAAO,MAAM;GAChC,cACE,OAAO,KAAK,IAAI,QAAQ,EAAE,QAAQ,qCAAqC,CAAC,CAAC;EAC7E,CAAC,CACH,EAAA,CAEmB,KAAK,OAAO,UAAU,UAAW,aAAa,YAAY,KAAM,CAAC;EAE1F,MAAM,WAAW,YACf,OAAO,IAAI,aAAa;GACtB,OAAO,QAAQ,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM;GACvC,MAAM,MAAM,OAAO,KAAK;GAExB,OAAO,IAAI,QAAQ;IAAE,MAAM;IAAO;IAAS,WAAW,MAAM;IAAI,IAAI,IAAI;GAAG,CAAC;EAC9E,CAAC;EAEH,IAAI,MAAM,OAAO,OAAO,QAAQ,SAAS;EACzC,IAAI,YAAY,OAAO,OAAO;EAC9B,MAAM,OAAO,KAAK,UAAU,KAAA,IAAY,KAAK,QAAQ,SAAS,KAAK;EAEnE,IAAI,SAAS,KAAA,GAAW,OAAO,OAAO,QAAQ,0BAA0B,KAAK,SAAS,GAAG,EAAE;EAC3F,MAAM,SAAS,YAAY,MAAM,MAAM,OAAO,KAAK,KAAK;EACxD,MAAM,QAAQ,OAAO,OAAO,KAAK,SAAS,MAAM,MAAM,IAAI,CAAC;EAE3D,IAAI,KAAK,UAAU,KAAK,GAAG;GACzB,MAAM,QAAQ,KAAK,gBAAgB,KAAK;GAExC,IAAI,OAAO,OAAO,KAAK,KAAK,MAAM,MAAM,SAAS,kBAAkB,MAAM,MAAM,YAAY;IACzF,QAAQ;IACR,IAAI,aAAa,KAAA,MAAc,WAAW,IAAI,KAAK,UAAU;KAC3D,MAAM,WAAW,OAAO,OAAO,KAAK,OAAO,QAAQ,MAAM,CAAC;KAE1D,IAAI,KAAK,UAAU,QAAQ,KAAK,SAAS,OAAO,OAAO,OAAO,QAAQ,UAAU;IAClF;GACF;GAEA,OAAO,OAAO,OAAO,UAAU,MAAM,KAAK;EAC5C;EACA,QAAQ;EACR,IAAI,aAAa,KAAA,KAAa,EAAE,OAAO,OAAO,QAAQ,MAAM,IAC1D,OAAO,OAAO,IAAI,QAAQ,EAAE,QAAQ,4CAA4C,CAAC;EAEnF,OAAO,OAAO,QAAQ,aAAa,KAAA,IAAY,UAAU,UAAU;CACrE,CAEiB,CAAC,CAAC,KACjB,OAAO,UACJ,WACC,IAAI,YAAY;EACd,MAAM;EACN;EACA;EACA,UAAU,CAAC;CACb,CAAC,CACL,CACF;AACF,CAAC;AAED,MAAM,MAAM,OAAO,WAAW,WAC5B,MACA,MACA,SACA,MACA,OACA,WACA;CACA,MAAM,WAA2B,CAAC;CAClC,MAAM,QAAQ,OAAO,SAAS,WAAW,OAAO,KAAK;CAErD,IACE,CAAC,OAAO,UAAU,KAAK,KACvB,QAAQ,KACR,QAAQ,KAAK,MAAM,UACnB,CAAC,OAAO,UAAU,KAAK,KACvB,QAAQ,SACR,QAAQ,KAAK,MAAM,QAEnB,OAAO,OAAO,IAAI,YAAY;EAC5B,MAAM;EACN,OAAO;EACP;EACA,QAAQ,QAAQ,qCAAqC;CACvD,CAAC;CAEH,IAAI,CAAC,aAAa,OAAO,SAAS,UAAU;EAC1C,MAAM,WAAW,KAAK,MAAM,WACzB,MAAM,UACL,SAAS,SAAS,KAAK,UAAU,KAAA,KAAa,QAAQ,SAAS,KAAK,WAAW,KAAA,CACnF;EAEA,IAAI,aAAa,IACf,OAAO,OAAO,IAAI,YAAY;GAC5B,MAAM;GACN,OAAO;GACP;GACA,QAAQ,QAAQ,0BAA0B,KAAK,MAAM,SAAS,EAAE,SAAS,GAAG,EAAE;EAChF,CAAC;CACL;CACA,KAAK,IAAI,QAAQ,OAAO,QAAQ,OAAO,SAAS;EAC9C,MAAM,KAAK,YACP,IAAI,QAAQ;GAAE,MAAM;GAAO,OAAO;EAAU,CAAC,IAC7C,UAAU,QACR,OACA;EAEN,MAAM,UAAU,OAAO,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,CAAC,KACnD,OAAO,UAAU,UAAU,IAAI,YAAY;GAAE,GAAG;GAAO,UAAU,CAAC,GAAG,QAAQ;EAAE,CAAC,CAAC,CACnF;EAEA,SAAS,KAAK,OAAO;CACvB;CAEA,OAAO;AACT,CAAC;;AAGD,MAAa,UAAU,MAAY,MAAY,UAAyB,CAAC,MACvE,IAAI,MAAM,MAAM,SAAS,QAAQ,QAAQ,GAAG,KAAK,MAAM,QAAQ,KAAK,CAAC,CAAC,KACpE,OAAO,SAAS,aAAa,CAC/B;;AAGF,MAAa,WACX,MACA,MACA,UAAgE,CAAC,MAEjE,IAAI,MAAM,MAAM,SAAS,GAAG,QAAQ,QAAQ,KAAK,MAAM,QAAQ,IAAI,CAAC,CAAC,KACnE,OAAO,SAAS,cAAc,CAChC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Supervisor-DaGlQVjv.mjs","names":["Lifecycle.GenerationState","Lifecycle.resolve","Lifecycle.lookup","Lifecycle.Settled","Lifecycle.Unconfirmed","Lifecycle.combine","Lifecycle.start","Lifecycle.transition"],"sources":["../src/internal/supervisor/lifecycle.ts","../src/Supervisor.ts"],"sourcesContent":["/**\n * A supervisor's life as one state and one transition function, and the generation states it\n * publishes. The transition has no effects: `Supervisor.make` applies each input under one lock,\n * publishes the events in order and runs the commands, so the rules here are tested alone.\n */\nimport { Schema } from \"effect\";\n\nimport { DisconnectCause } from \"../../BrowserEvent.ts\";\n\n/** The provider confirmed that the generation's browser ended. */\nexport class Settled extends Schema.TaggedClass<Settled>()(\"Settled\", {}) {}\n\n/** The provider could not confirm the end by its deadline, so the browser may still run, and bill. */\nexport class Unconfirmed extends Schema.TaggedClass<Unconfirmed>()(\"Unconfirmed\", {\n detail: Schema.String,\n}) {}\n\nexport const Released = Schema.Union([Settled, Unconfirmed]);\n\nexport type Released = typeof Released.Type;\n\n/** Opening, but not after a loss: the first generation, a rotation, or the one after `Down`. */\nexport class Opening extends Schema.TaggedClass<Opening>()(\"Opening\", {}) {}\n\n/** Opening after the generation before it was lost. */\nexport class Reopening extends Schema.TaggedClass<Reopening>()(\"Reopening\", {}) {}\n\n/** Open: `browser` gives this generation until the next one opens. */\nexport class Open extends Schema.TaggedClass<Open>()(\"Open\", {}) {}\n\n/** No longer serving; holds end at this host-monotonic deadline or when their owners let go. */\nexport class Draining extends Schema.TaggedClass<Draining>()(\"Draining\", {\n reason: Schema.Literals([\"rotated\", \"lost\", \"retired\"]),\n revokeAt: Schema.Finite,\n}) {}\n\n/** Lost through disconnection or a consumer's declaration that it is unusable. */\nexport class Lost extends Schema.TaggedClass<Lost>()(\"Lost\", {\n cause: Schema.Union([DisconnectCause, Schema.Literal(\"declared\")]),\n detail: Schema.optional(Schema.String),\n}) {}\n\n/**\n * It never opened: its last try failed with `cause`, which the provider deems definite, or after\n * which the reopen schedule gave up.\n */\nexport class Down extends Schema.TaggedClass<Down>()(\"Down\", {\n detail: Schema.String,\n cause: Schema.Defect(),\n}) {}\n\n/** It ended. `released` says how its release went; one retired while opening has none. */\nexport class Closed extends Schema.TaggedClass<Closed>()(\"Closed\", {\n released: Schema.optional(Released),\n}) {}\n\n/**\n * It was serving as the supervisor's scope closed, and was left running, not released: its scope\n * closed, and its provider runs it on, and bills, until something adopts and releases it.\n */\nexport class Kept extends Schema.TaggedClass<Kept>()(\"Kept\", {}) {}\n\nexport const GenerationState = Schema.Union([\n Opening,\n Reopening,\n Open,\n Draining,\n Lost,\n Down,\n Closed,\n Kept,\n]);\n\nexport type GenerationState = typeof GenerationState.Type;\n\n/** A generation that opened: its number, and what the runtime keeps to serve and end it. */\nexport interface Live<A> {\n readonly number: number;\n readonly value: A;\n}\n\nexport interface Held<A, H> extends Live<A> {\n readonly holds: ReadonlySet<H>;\n}\n\n/** Release ownership remains here until the provider and generation scope have finished. */\nexport interface Drain<A, H> {\n readonly _tag: \"Draining\" | \"Releasing\" | \"Leaving\";\n readonly live: Held<A, H>;\n readonly ending: Draining;\n}\n\n/** One serving generation, one shared acquisition, and prior generations still owned. */\nexport type State<A, H = unknown> = (\n | { readonly _tag: \"Opening\"; readonly number: number; readonly serving: Held<A, H> | undefined }\n | { readonly _tag: \"Open\"; readonly serving: Held<A, H> }\n | {\n readonly _tag: \"Down\";\n readonly number: number;\n readonly detail: string;\n readonly cause: unknown;\n readonly serving: Held<A, H> | undefined;\n }\n | { readonly _tag: \"Retired\" }\n) & {\n readonly draining: ReadonlyMap<number, Drain<A, H>>;\n /** Retain the first unconfirmed end, otherwise the latest settled end, without its resources. */\n readonly released?: Released | undefined;\n};\n\nexport type Input<A, H = unknown> =\n | { readonly _tag: \"Opened\"; readonly live: Live<A> }\n | { readonly _tag: \"AttemptReleased\"; readonly released: Released }\n | {\n readonly _tag: \"Failed\";\n readonly number: number;\n readonly detail: string;\n readonly cause: unknown;\n }\n | { readonly _tag: \"Abandoned\"; readonly number: number }\n | {\n readonly _tag: \"Lost\";\n readonly number: number;\n readonly cause: Lost[\"cause\"];\n readonly detail?: string | undefined;\n }\n | { readonly _tag: \"Rotate\"; readonly due?: number | undefined }\n | { readonly _tag: \"Retire\" }\n | { readonly _tag: \"Keep\" }\n | {\n readonly _tag: \"Hold\";\n readonly number?: number | undefined;\n readonly hold: H;\n }\n | { readonly _tag: \"Let\"; readonly number: number; readonly hold: H }\n | { readonly _tag: \"Revoke\"; readonly number: number }\n | {\n readonly _tag: \"Released\";\n readonly number: number;\n readonly released?: Released | undefined;\n };\n\nexport type Command<A> =\n | { readonly _tag: \"Open\"; readonly number: number }\n | { readonly _tag: \"Watch\"; readonly live: Live<A> }\n /** Signal ending and arrange revocation. Repeated only when loss/retirement accelerates it. */\n | { readonly _tag: \"Drain\"; readonly live: Live<A>; readonly ending: Draining }\n /** Revoke/close holds, await their Let inputs, release the provider, then close its scope. */\n | { readonly _tag: \"Release\"; readonly live: Live<A>; readonly ending: Draining }\n | { readonly _tag: \"Leave\"; readonly live: Live<A>; readonly ending: Draining };\n\nexport interface Step<A, H = unknown> {\n readonly state: State<A, H>;\n readonly events: ReadonlyArray<readonly [number, GenerationState]>;\n readonly commands: ReadonlyArray<Command<A>>;\n readonly reply?: number | undefined;\n readonly borrowed?: Live<A> | undefined;\n}\n\nexport const start = <A, H = unknown>(): Step<A, H> => ({\n state: { _tag: \"Opening\", number: 1, serving: undefined, draining: new Map() },\n events: [[1, new Opening()]],\n commands: [{ _tag: \"Open\", number: 1 }],\n});\n\nconst servingOf = <A, H>(state: State<A, H>) =>\n state._tag === \"Retired\" ? undefined : state.serving;\n\n/** The holds still owned for a generation, including one whose release has begun. */\nexport const lookup = <A, H>(state: State<A, H>, number: number): Held<A, H> | undefined =>\n servingOf(state)?.number === number ? servingOf(state) : state.draining.get(number)?.live;\n\n/** A transition's local result builder; input state and its collections remain immutable. */\ninterface Change<A, H> {\n readonly now: number;\n readonly handover: number;\n readonly exclusive: boolean;\n state: State<A, H>;\n events: Array<readonly [number, GenerationState]>;\n commands: Array<Command<A>>;\n reply?: number;\n borrowed?: Live<A>;\n}\n\n/** The sole writer of a drain's ending and phase; each release command is emitted once. */\nconst draining = <A, H>(change: Change<A, H>, drain: Drain<A, H>) => {\n const before = change.state.draining.get(drain.live.number);\n const { live, ending, _tag } = drain;\n\n change.state = {\n ...change.state,\n draining: new Map(change.state.draining).set(live.number, drain),\n };\n if (before?.ending !== ending) {\n change.events.push([live.number, ending]);\n change.commands.push({ _tag: \"Drain\", live, ending });\n }\n if (_tag !== \"Draining\" && before?._tag !== _tag)\n change.commands.push({ _tag: _tag === \"Leaving\" ? \"Leave\" : \"Release\", live, ending });\n};\n\nconst end = <A, H>(\n change: Change<A, H>,\n live: Held<A, H>,\n reason: Draining[\"reason\"],\n keep = false,\n) => {\n const ending = new Draining({\n reason,\n revokeAt: change.now + (reason === \"rotated\" ? change.handover : 0),\n });\n\n draining(change, {\n live,\n ending,\n _tag: keep\n ? \"Leaving\"\n : live.holds.size === 0 || ending.revokeAt <= change.now\n ? \"Releasing\"\n : \"Draining\",\n });\n};\n\nconst revoke = <A, H>(change: Change<A, H>, number: number, reason?: \"lost\" | \"retired\") => {\n const drain = change.state.draining.get(number);\n\n if (drain?._tag !== \"Draining\" || (reason === undefined && change.now < drain.ending.revokeAt))\n return;\n draining(change, {\n ...drain,\n _tag: \"Releasing\",\n ending: reason === undefined ? drain.ending : new Draining({ reason, revokeAt: change.now }),\n });\n};\n\nconst holds = <A, H>(\n change: Change<A, H>,\n input: Extract<Input<A, H>, { readonly _tag: \"Hold\" | \"Let\" }>,\n) => {\n const number = input.number ?? servingOf(change.state)?.number;\n const live = number === undefined ? undefined : lookup(change.state, number);\n\n if (live === undefined) return;\n const drain = change.state.draining.get(live.number);\n\n if (\n input._tag === \"Hold\" &&\n drain !== undefined &&\n (drain._tag !== \"Draining\" || change.now >= drain.ending.revokeAt)\n )\n return;\n if (live.holds.has(input.hold) === (input._tag === \"Hold\")) return;\n const holds = new Set(live.holds);\n\n if (input._tag === \"Hold\") {\n holds.add(input.hold);\n change.borrowed = live;\n } else holds.delete(input.hold);\n const held = { ...live, holds };\n\n if (drain !== undefined)\n draining(change, {\n ...drain,\n live: held,\n _tag: drain._tag === \"Draining\" && holds.size === 0 ? \"Releasing\" : drain._tag,\n });\n else if (change.state._tag !== \"Retired\") change.state = { ...change.state, serving: held };\n};\n\nconst next = <A, H>(change: Change<A, H>, number: number, reopen: boolean) => {\n const { exclusive } = change;\n const current = servingOf(change.state);\n\n if (current !== undefined && (reopen || exclusive))\n end(change, current, reopen ? \"lost\" : \"rotated\");\n change.state = {\n _tag: \"Opening\",\n number,\n serving: reopen || exclusive ? undefined : current,\n draining: change.state.draining,\n released: change.state.released,\n };\n change.events.push([number, reopen ? new Reopening() : new Opening()]);\n change.commands.push({ _tag: \"Open\", number });\n};\n\nconst lost = <A, H>(\n change: Change<A, H>,\n input: Extract<Input<A, H>, { readonly _tag: \"Lost\" }>,\n) => {\n const { state } = change;\n const drain = state.draining.get(input.number);\n const current = servingOf(state);\n\n if (input.cause === \"declared\" && current?.number !== input.number) return;\n if (drain?._tag === \"Draining\") {\n change.events.push([input.number, new Lost({ cause: input.cause })]);\n revoke(change, input.number, \"lost\");\n } else if (state._tag !== \"Retired\" && current?.number === input.number) {\n change.events.push([input.number, new Lost({ cause: input.cause, detail: input.detail })]);\n if (state._tag !== \"Opening\")\n next(change, (state._tag === \"Open\" ? current.number : state.number) + 1, true);\n else {\n change.state = { ...state, serving: undefined };\n end(change, current, \"lost\");\n }\n }\n};\n\n/** Pure admission and lifecycle changes. A rejected hold preserves state identity. */\nexport const transition = <A, H = unknown>(\n state: State<A, H>,\n input: Input<A, H>,\n exclusive: boolean,\n now = 0,\n handover = 30_000,\n): Step<A, H> => {\n const change: Change<A, H> = {\n state,\n events: [],\n commands: [],\n exclusive,\n handover,\n now,\n };\n\n switch (input._tag) {\n case \"Hold\":\n case \"Let\":\n holds(change, input);\n break;\n case \"Revoke\":\n revoke(change, input.number);\n break;\n case \"Opened\": {\n const live = { ...input.live, holds: new Set<H>() };\n\n if (lookup(state, live.number) !== undefined) break;\n if (state._tag !== \"Opening\" || state.number !== live.number) end(change, live, \"retired\");\n else {\n change.events.push([live.number, new Open()]);\n change.commands.push({ _tag: \"Watch\", live });\n if (state.serving !== undefined) end(change, state.serving, \"rotated\");\n change.state = {\n _tag: \"Open\",\n serving: live,\n draining: change.state.draining,\n released: change.state.released,\n };\n }\n break;\n }\n case \"Failed\": {\n const { number, detail, cause } = input;\n\n if (state._tag === \"Opening\" && state.number === number)\n change.state = { ...state, _tag: \"Down\", detail, cause };\n change.events.push([number, new Down({ detail, cause })]);\n break;\n }\n case \"Abandoned\":\n change.events.push([input.number, new Closed({})]);\n break;\n case \"AttemptReleased\":\n change.state = { ...state, released: combine(state.released, input.released) };\n break;\n case \"Released\": {\n const drain = state.draining.get(input.number);\n\n if (drain === undefined || drain._tag === \"Draining\" || drain.live.holds.size > 0) break;\n const draining = new Map(state.draining);\n\n draining.delete(input.number);\n change.state = { ...state, draining, released: combine(state.released, input.released) };\n change.events.push([\n input.number,\n input.released === undefined ? new Kept() : new Closed({ released: input.released }),\n ]);\n break;\n }\n case \"Lost\":\n lost(change, input);\n break;\n case \"Rotate\": {\n if (\n state._tag === \"Retired\" ||\n (input.due !== undefined && (state._tag !== \"Open\" || state.serving.number !== input.due))\n )\n break;\n change.reply =\n state._tag === \"Opening\"\n ? state.number\n : (state._tag === \"Open\" ? state.serving.number : state.number) + 1;\n if (state._tag !== \"Opening\") next(change, change.reply, false);\n break;\n }\n case \"Keep\":\n case \"Retire\":\n if (state._tag === \"Retired\") break;\n for (const number of state.draining.keys()) revoke(change, number, \"retired\");\n if (state.serving !== undefined) end(change, state.serving, \"retired\", input._tag === \"Keep\");\n change.state = {\n _tag: \"Retired\",\n draining: change.state.draining,\n released: change.state.released,\n };\n }\n\n return change;\n};\n\n/** Later confirmations cannot establish that an earlier unconfirmed session ended. */\nexport const combine = (before: Released | undefined, next: Released | undefined) =>\n before?._tag === \"Unconfirmed\" ? before : (next ?? before);\n\nexport type Resolution<A> =\n | { readonly _tag: \"Serve\"; readonly live: Live<A> }\n | {\n readonly _tag: \"Unavailable\";\n readonly reason: \"down\" | \"retired\";\n readonly detail: string;\n readonly cause?: unknown;\n };\n\n/** An unheld browser resolution; use obtains its hold atomically through Hold instead. */\nexport const resolve = <A, H>(\n state: State<A, H>,\n target: number | undefined,\n): Resolution<A> | undefined => {\n if (state._tag === \"Retired\")\n return { _tag: \"Unavailable\", reason: \"retired\", detail: \"the supervisor was retired\" };\n if (\n state.serving !== undefined &&\n (target === undefined || (state._tag === \"Open\" && state.serving.number >= target))\n )\n return { _tag: \"Serve\", live: state.serving };\n if (state._tag === \"Down\" && (target === undefined || state.number >= target))\n return { _tag: \"Unavailable\", reason: \"down\", detail: state.detail, cause: state.cause };\n\n return undefined;\n};\n","/**\n * A browser kept open across losses and session ends, as a series of generations, each a new\n * browser from the same provider. Pages don't carry over from one generation to the next.\n *\n * `make` opens the first generation at once with the provider's `open`, in a scope of its own, so\n * a caller that stops waiting never interrupts a half-open browser. `browser` gives the current\n * generation; callers wait, bounded, and share one open. A loss is published at once and the next\n * generation opens on the `reopen` schedule, which also retries a failed open, unless the provider\n * deems its failure `definite`: that goes `Down` at once, with its cause. `rotate` opens the\n * next generation now, and so does the time `rotateBefore` ahead of a generation's `expiresAt`. A\n * rotation makes the next generation before it breaks the current one, unless generations are\n * `exclusive`, as sessions saving to one stored context must be: then the current one is released\n * first. `retire` stops reopening at once and releases what is open; the scope's close retires\n * too, unless the supervisor `keep`s: then it leaves the serving generation running, `Kept`. `states`\n * publishes each generation's changes, with the provider's release outcome last.\n *\n * Providers supply the specifics: `Browserbase.supervise` opens hosted sessions this way.\n *\n * @since 0.3.0\n */\nimport {\n Cause,\n Clock,\n Context,\n DateTime,\n Deferred,\n Duration,\n Effect,\n Exit,\n FiberHandle,\n FiberMap,\n Option,\n Predicate,\n PubSub,\n Schedule,\n Schema,\n Scope,\n Semaphore,\n Stream,\n SubscriptionRef,\n type Take,\n} from \"effect\";\n\nimport type * as Browser from \"./Browser.ts\";\nimport * as Lifecycle from \"./internal/supervisor/lifecycle.ts\";\n\nexport {\n Closed,\n Down,\n Draining,\n GenerationState,\n Kept,\n Lost,\n Open,\n Opening,\n Released,\n Reopening,\n Settled,\n Unconfirmed,\n} from \"./internal/supervisor/lifecycle.ts\";\n\n/** One change in a generation's life. `at` is wall-clock epoch milliseconds from the Effect `Clock`. */\nexport class Generation extends Schema.Class<Generation>(\"effect-browser/Generation\")({\n number: Schema.Int.check(Schema.isGreaterThan(0)),\n at: Schema.Finite,\n hostTime: Schema.Finite,\n state: Lifecycle.GenerationState,\n}) {}\n\n/**\n * No browser to give: none opened within `waitTimeout` (`opening`), the latest generation failed\n * to open (`down`, with what it failed with as `cause`), or the supervisor was retired.\n */\nexport class Unavailable extends Schema.TaggedError<Unavailable>()(\"Unavailable\", {\n reason: Schema.Literals([\"opening\", \"down\", \"retired\"]),\n detail: Schema.String,\n cause: Schema.optional(Schema.Defect()),\n}) {\n override get message() {\n return `no browser: ${this.detail}`;\n }\n}\n\n/** One generation, as a provider opened it in the scope the supervisor gave it. */\nexport interface Opened<A = void> {\n readonly value: A;\n readonly browser: Browser.Service;\n /**\n * End the generation, and say whether the provider confirmed its end. The supervisor asks it\n * before it closes the generation's scope; without it, closing the scope ends the generation,\n * which counts as `Settled`.\n */\n readonly release?: Effect.Effect<Lifecycle.Released> | undefined;\n}\n\n/** Facts available before an acquisition attempt; awaiting `after` never changes release order. */\nexport interface Admission {\n readonly number: number;\n /**\n * Every earlier session that stopped serving, including failed attempts and older drains.\n * Waits for all pending releases; an Unconfirmed end remains visible to later attempts.\n * Undefined before any release. A still-serving nonexclusive predecessor is excluded.\n */\n readonly after: Effect.Effect<Lifecycle.Released> | undefined;\n}\n\n/**\n * Optional service supplied during `open`. Providers report failed-attempt cleanup here before\n * their scope closes; successful generations instead return `Opened.release`. Reporting does\n * not release resources or replace the original acquisition failure.\n */\nexport class Releasing extends Context.Service<\n Releasing,\n { readonly released: (outcome: Lifecycle.Released) => Effect.Effect<void> }\n>()(\"effect-browser/Supervisor/Releasing\") {}\n\nexport interface Options<E, R, A = void> {\n /** Opens one generation in the scope it is given. */\n readonly open: Effect.Effect<Opened<A>, E, R>;\n /** Runs before every open attempt, including the first; failures follow `reopen` and `definite`. */\n readonly admit?: ((opening: Admission) => Effect.Effect<void, E, R>) | undefined;\n /** When to try a failed open again. Defaults to exponential from 1 second, for 5 minutes. */\n readonly reopen?: Schedule.Schedule<unknown, E> | undefined;\n /**\n * Failures no new try mends, such as a refused key: an open that fails so is `Down` at once.\n * Defaults to none.\n */\n readonly definite?: ((error: E) => boolean) | undefined;\n /**\n * Rotate this long ahead of a generation's `expiresAt`, but no sooner than halfway through its\n * life. Without it, a generation's end is a loss.\n */\n readonly rotateBefore?: Duration.Input | undefined;\n /** Generations must not overlap: a rotation releases the current one before it opens the next. */\n readonly exclusive?: boolean | undefined;\n /** Finite, nonnegative time outgoing holds may finish; defaults to 30 seconds. */\n readonly handover?: Duration.Input | undefined;\n /**\n * Closing the scope leaves the serving generation running, `Kept`: it closes the generation's\n * scope but never asks `release`. For providers whose scope only disconnects, such as\n * `Browserbase.supervise` with `keep`. `retire` still releases it.\n */\n readonly keep?: boolean | undefined;\n /** How long `browser` and `rotate` wait for a generation to open. Defaults to 2 minutes. */\n readonly waitTimeout?: Duration.Input | undefined;\n}\n\n/** Work whose generation was revoked; input receipts still determine whether input reached a site. */\nexport class Superseded extends Schema.TaggedError<Superseded>()(\"Superseded\", {\n generation: Schema.Int,\n reason: Schema.Literals([\"rotated\", \"lost\", \"retired\"]),\n revokeAt: Schema.Finite,\n}) {}\n\nexport interface Lease<A> {\n readonly generation: number;\n readonly browser: Browser.Service;\n readonly value: A;\n /** Declare this serving generation unusable and revoke it now; stale declarations do nothing. */\n readonly lose: (detail: string) => Effect.Effect<void>;\n /** First notice that serving ended; loss or retirement may revoke before its deadline. */\n readonly ending: Effect.Effect<Superseded>;\n /** An independent scope; its resources close before provider release. Fails once revoked. */\n readonly retain: Effect.Effect<Scope.Closeable, Superseded>;\n}\n\nexport interface UseOptions {\n /** Finite, nonnegative wait for a serving generation. Zero makes an immediate attempt. */\n readonly wait?: Duration.Input | undefined;\n}\n\nexport interface Supervisor<A = void> {\n /** Scoped work on the current generation. Revocation interrupts it and waits for its cleanup. */\n readonly use: <B, E, R>(\n work: (lease: Lease<A>) => Effect.Effect<B, E, R>,\n options?: UseOptions,\n ) => Effect.Effect<B, E | Unavailable | Superseded, Exclude<R, Scope.Scope>>;\n /** The current generation's browser, waiting up to `waitTimeout` while none is open. */\n readonly browser: Effect.Effect<Browser.Service, Unavailable>;\n /** Each generation's changes, in order. A new reader first gets the latest 64; ends on retiring. */\n readonly states: Stream.Stream<Generation>;\n /** Open the next generation now, or join the one opening, and wait for it. */\n readonly rotate: Effect.Effect<Browser.Service, Unavailable>;\n /** Stop opening at once, release every generation, and wait until each release has finished. */\n readonly retire: Effect.Effect<void>;\n}\n\ntype Hold =\n | { readonly _tag: \"Use\" }\n | { readonly _tag: \"Retained\"; readonly scope: Scope.Closeable };\n\ninterface Held<A> {\n readonly opened: Opened<A>;\n readonly ending: Deferred.Deferred<Superseded>;\n readonly revoked: Deferred.Deferred<Superseded>;\n readonly released: Deferred.Deferred<Lifecycle.Released>;\n readonly scope: Scope.Closeable;\n}\n\ntype State<A> = Lifecycle.State<Held<A>, Hold>;\ntype Input<A> = Lifecycle.Input<Held<A>, Hold>;\ntype Step<A> = Lifecycle.Step<Held<A>, Hold>;\ntype Apply<A> = (input: Input<A>) => Effect.Effect<Step<A>>;\n\nconst superseded = (generation: number, { reason, revokeAt }: Lifecycle.Draining) =>\n new Superseded({ generation, reason, revokeAt });\n\nconst retired = () => new Unavailable({ reason: \"retired\", detail: \"the supervisor was retired\" });\n\nconst describe = (cause: Cause.Cause<unknown>) => {\n const error = Cause.squash(cause);\n\n return Predicate.isError(error) ? error.message : String(error);\n};\n\nconst timedOut = () =>\n new Unavailable({ reason: \"opening\", detail: \"no generation opened within the wait\" });\n\nconst bounded = (input: Duration.Input, name: string) =>\n Effect.suspend(() => {\n const duration = Duration.fromInput(input);\n\n return Option.isSome(duration) &&\n Duration.isFinite(duration.value) &&\n !Duration.isNegative(duration.value)\n ? Effect.succeed(duration.value)\n : Effect.die(new RangeError(`${name} must be a finite nonnegative duration`));\n });\n\n/** Resolve immediately before starting a bounded wait, including when its duration is zero. */\nconst waitFor = <A, H>(\n state: SubscriptionRef.SubscriptionRef<Lifecycle.State<A, H>>,\n wait: Duration.Duration,\n clock: Clock.Clock,\n target?: number,\n) => {\n const result = (resolution: Lifecycle.Resolution<A>) =>\n resolution._tag === \"Serve\"\n ? Effect.succeed(resolution.live)\n : Effect.fail(new Unavailable(resolution));\n\n return Effect.suspend(() => {\n const current = Lifecycle.resolve(state.value, target);\n\n return current === undefined\n ? SubscriptionRef.changes(state).pipe(\n Stream.map((state) => Lifecycle.resolve(state, target)),\n Stream.filter(Predicate.isNotUndefined),\n Stream.runHead,\n Effect.flatMap(Option.match({ onNone: () => Effect.fail(retired()), onSome: result })),\n Effect.timeoutOrElse({ duration: wait, orElse: () => Effect.fail(timedOut()) }),\n )\n : result(current);\n }).pipe(Effect.provideService(Clock.Clock, clock));\n};\n\n/** Sleep until `before` ahead of `expiresAt`, but no sooner than halfway there from now. */\nconst untilRotation = (expiresAt: DateTime.Utc, before: Duration.Duration) =>\n Clock.currentTimeMillis.pipe(\n Effect.flatMap((now) => {\n const left = DateTime.toEpochMillis(expiresAt) - now;\n\n return Effect.sleep(Duration.millis(Math.max(left - Duration.toMillis(before), left / 2, 0)));\n }),\n );\n\n/** Native timers may wake a fraction early; a revocation must reach its monotonic deadline. */\nconst until = (at: number, now: () => number): Effect.Effect<void> =>\n Effect.suspend(() =>\n now() >= at\n ? Effect.void\n : Effect.sleep(Duration.millis(Math.ceil(at - now()))).pipe(Effect.andThen(until(at, now))),\n );\n\n/** Borrowed work and transferred scopes hold a generation until cleanup lets it go. */\nconst leasing = <A>(\n state: SubscriptionRef.SubscriptionRef<State<A>>,\n apply: Apply<A>,\n waitTimeout: Duration.Duration,\n now: () => number,\n clock: Clock.Clock,\n) => {\n const borrow = Effect.fnUntraced(function* (hold: Hold, wait: Duration.Duration) {\n const until = now() + Duration.toMillis(wait);\n\n for (;;) {\n const step = yield* apply({ _tag: \"Hold\", hold });\n\n if (step.borrowed !== undefined) return step.borrowed;\n yield* waitFor(state, Duration.millis(Math.max(0, until - now())), clock).pipe(\n Effect.interruptible,\n );\n if (now() >= until) return yield* timedOut();\n }\n });\n\n const leaseOf = (live: Lifecycle.Live<Held<A>>): Lease<A> => ({\n generation: live.number,\n browser: live.value.opened.browser,\n value: live.value.opened.value,\n lose: (detail) =>\n apply({ _tag: \"Lost\", number: live.number, cause: \"declared\", detail }).pipe(Effect.asVoid),\n ending: Deferred.await(live.value.ending),\n retain: Effect.uninterruptible(\n Effect.gen(function* () {\n const scope = yield* Scope.make();\n const hold: Hold = { _tag: \"Retained\", scope };\n const step = yield* apply({ _tag: \"Hold\", number: live.number, hold });\n\n if (step.borrowed === undefined) {\n yield* Scope.close(scope, Exit.void);\n\n return yield* yield* Deferred.await(live.value.ending);\n }\n yield* Scope.addFinalizer(\n scope,\n apply({ _tag: \"Let\", number: live.number, hold }).pipe(Effect.asVoid),\n );\n\n return scope;\n }),\n ),\n });\n\n const use: Supervisor<A>[\"use\"] = (work, options = {}) =>\n Effect.scoped(\n Effect.gen(function* () {\n const hold: Hold = { _tag: \"Use\" };\n const wait = yield* bounded(options.wait ?? waitTimeout, \"wait\");\n\n const live = yield* Effect.acquireRelease(borrow(hold, wait), (live) =>\n apply({ _tag: \"Let\", number: live.number, hold }).pipe(Effect.asVoid),\n );\n\n const revoked = Deferred.await(live.value.revoked).pipe(Effect.flatMap(Effect.fail));\n\n return yield* Effect.raceFirst(\n work(leaseOf(live)).pipe(\n // Declaring loss and returning can finish before the race's other fiber runs.\n Effect.tap(() =>\n Deferred.isDone(live.value.revoked).pipe(\n Effect.flatMap((done) => (done ? revoked : Effect.void)),\n ),\n ),\n ),\n revoked,\n );\n }),\n );\n\n return use;\n};\n\ntype Provider = Omit<Opened, \"value\">;\ntype MakeOptions<E, R, A> = Omit<Options<E, R, A>, \"open\"> & {\n readonly open: Effect.Effect<Opened<A> | Provider, E, R>;\n};\n\nconst acquireGeneration = <A, E, R>(\n open: Effect.Effect<Opened<A> | Provider, E, R>,\n own: Scope.Scope,\n) =>\n Effect.uninterruptibleMask((restore) =>\n Effect.flatMap(Scope.fork(own), (scope) =>\n restore(open.pipe(Scope.provide(scope))).pipe(\n Effect.onError((cause) => Scope.close(scope, Exit.failCause(cause))),\n Effect.map((opened): Held<A | void> => ({\n opened: { ...opened, value: \"value\" in opened ? opened.value : undefined },\n scope,\n ending: Deferred.makeUnsafe<Superseded>(),\n revoked: Deferred.makeUnsafe<Superseded>(),\n released: Deferred.makeUnsafe<Lifecycle.Released>(),\n })),\n ),\n ),\n );\n\nconst watchGeneration = <A>(\n live: Lifecycle.Live<Held<A>>,\n rotateBefore: Duration.Duration | undefined,\n apply: Apply<A>,\n) => {\n const { browser } = live.value.opened;\n\n const loss = browser.disconnected.pipe(\n Effect.flatMap((cause) => apply({ _tag: \"Lost\", number: live.number, cause })),\n );\n\n const rotation =\n browser.expiresAt === undefined || rotateBefore === undefined\n ? Effect.void\n : untilRotation(browser.expiresAt, rotateBefore).pipe(\n Effect.andThen(apply({ _tag: \"Rotate\", due: live.number })),\n );\n\n return Effect.all([loss, rotation], { concurrency: 2, discard: true });\n};\n\n// After revocation, retained resources and use finalizers let go before the provider.\nconst releaseGeneration = Effect.fnUntraced(function* <A>(\n command: Extract<Lifecycle.Command<Held<A>>, { readonly _tag: \"Release\" | \"Leave\" }>,\n state: SubscriptionRef.SubscriptionRef<State<A>>,\n apply: Apply<A>,\n) {\n const { live } = command;\n\n const cleaned = yield* Effect.forEach(\n Lifecycle.lookup(state.value, live.number)?.holds ?? [],\n (hold) =>\n Effect.exit(hold._tag === \"Retained\" ? Scope.close(hold.scope, Exit.void) : Effect.void),\n { concurrency: 8 },\n );\n\n yield* SubscriptionRef.changes(state).pipe(\n Stream.filter((current) => (Lifecycle.lookup(current, live.number)?.holds.size ?? 0) === 0),\n Stream.runHead,\n );\n\n const released =\n command._tag === \"Leave\"\n ? undefined\n : yield* (live.value.opened.release ?? Effect.succeed(new Lifecycle.Settled())).pipe(\n Effect.catchCause((cause) =>\n Effect.succeed(\n new Lifecycle.Unconfirmed({ detail: `the release failed: ${describe(cause)}` }),\n ),\n ),\n );\n\n const closed = yield* Effect.exit(Scope.close(live.value.scope, Exit.void));\n\n yield* apply({ _tag: \"Released\", number: live.number, released });\n if (released !== undefined) yield* Deferred.succeed(live.value.released, released);\n yield* Exit.asVoidAll([...cleaned, closed]);\n});\n\nconst admissionAfter = <A>(state: State<A>) => {\n const released = state.released;\n\n const pending = [...state.draining.values()]\n .filter((drain) => drain._tag !== \"Leaving\")\n .map(({ live }) => live.value.released);\n\n return pending.length === 0 && released === undefined\n ? undefined\n : Effect.gen(function* () {\n let outcome = released;\n\n for (const release of pending)\n outcome = Lifecycle.combine(outcome, yield* Deferred.await(release));\n\n return outcome ?? new Lifecycle.Settled();\n });\n};\n\nconst makeScoped = Effect.fn(\"Supervisor.make\")(function* <E, R, A>(\n options: MakeOptions<E, R, A>,\n): Effect.fn.Return<Supervisor<A | void>, never, Scope.Scope | Exclude<R, Scope.Scope>> {\n const clock = yield* Clock.Clock;\n const now = () => Number(clock.monotonicTimeNanosUnsafe()) / 1e6;\n const context = yield* Effect.context<Exclude<R, Scope.Scope>>();\n const own = yield* Scope.fork(yield* Effect.scope);\n const exclusive = options.exclusive ?? false;\n\n const reopen: Schedule.Schedule<unknown, E> =\n options.reopen ??\n Schedule.exponential(\"1 second\").pipe(Schedule.upTo({ duration: Duration.minutes(5) }));\n\n const rotateBefore =\n options.rotateBefore === undefined ? undefined : Duration.fromInputUnsafe(options.rotateBefore);\n\n const waitTimeout = yield* bounded(options.waitTimeout ?? Duration.minutes(2), \"waitTimeout\");\n\n const handover = Duration.toMillis(\n yield* bounded(options.handover ?? Duration.seconds(30), \"handover\"),\n );\n\n const started = Lifecycle.start<Held<A | void>, Hold>();\n const state = yield* SubscriptionRef.make(started.state);\n const applying = yield* Semaphore.make(1);\n const events = yield* PubSub.unbounded<Take.Take<Generation>>({ replay: 64 });\n const opening = yield* FiberHandle.make<unknown, never>();\n const releases = yield* FiberMap.make<number, unknown, never>();\n const runOpen = yield* FiberHandle.runtime(opening)();\n const runRelease = yield* FiberMap.runtime(releases)();\n\n const apply: Apply<A | void> = Effect.fnUntraced(\n function* (input: Input<A | void>) {\n const current = state.value;\n const step = Lifecycle.transition(current, input, exclusive, now(), handover);\n\n if (step.state !== current) yield* SubscriptionRef.set(state, step.state);\n yield* perform(step);\n\n return step;\n },\n (effect) => applying.withPermit(effect),\n Effect.uninterruptible,\n Effect.provideService(Clock.Clock, clock),\n );\n\n const perform = Effect.fnUntraced(function* (step: Step<A | void>): Effect.fn.Return<void> {\n for (const [number, generation] of step.events)\n PubSub.publishUnsafe(events, [\n new Generation({\n number,\n at: clock.currentTimeMillisUnsafe(),\n hostTime: now(),\n state: generation,\n }),\n ]);\n for (const command of step.commands)\n switch (command._tag) {\n case \"Open\":\n runOpen(openGeneration(command.number));\n break;\n case \"Watch\":\n yield* Effect.forkIn(\n Effect.provideContext(watchGeneration(command.live, rotateBefore, apply), context),\n command.live.value.scope,\n );\n break;\n case \"Drain\": {\n const ending = superseded(command.live.number, command.ending);\n\n yield* Deferred.succeed(command.live.value.ending, ending);\n yield* Effect.forkIn(\n until(ending.revokeAt, now).pipe(\n Effect.andThen(\n Effect.suspend(() => apply({ _tag: \"Revoke\", number: command.live.number })),\n ),\n ),\n command.live.value.scope,\n );\n break;\n }\n case \"Release\":\n case \"Leave\":\n yield* Deferred.succeed(\n command.live.value.revoked,\n superseded(command.live.number, command.ending),\n );\n runRelease(command.live.number, releaseGeneration(command, state, apply));\n break;\n }\n });\n\n const openGeneration = (number: number) => {\n const openOnce = acquireGeneration(\n Effect.gen(function* () {\n const after = admissionAfter(state.value);\n\n if (exclusive && after !== undefined) yield* after;\n yield* options.admit?.({ number, after }) ?? Effect.void;\n\n return yield* options.open.pipe(\n Effect.provideService(Releasing, {\n released: (released) =>\n apply({ _tag: \"AttemptReleased\", released }).pipe(Effect.asVoid),\n }),\n );\n }),\n own,\n ).pipe(Effect.provideContext(context));\n\n return Effect.uninterruptibleMask((restore) =>\n restore(\n Effect.retry(openOnce, {\n schedule: reopen,\n while: (error) => !options.definite?.(error),\n }),\n ).pipe(\n Effect.exit,\n Effect.flatMap((exit) => {\n if (Exit.isSuccess(exit))\n return apply({ _tag: \"Opened\", live: { number, value: exit.value } });\n const cause = exit.cause;\n\n return apply(\n Cause.hasInterruptsOnly(cause)\n ? { _tag: \"Abandoned\", number }\n : { _tag: \"Failed\", number, detail: describe(cause), cause: Cause.squash(cause) },\n );\n }),\n ),\n );\n };\n\n const end = yield* Effect.cached(PubSub.publish(events, Exit.void));\n\n const stop = Effect.fnUntraced(function* (input: Input<A | void>) {\n yield* apply(input);\n yield* FiberHandle.clear(opening);\n yield* FiberMap.awaitEmpty(releases);\n if (yield* Deferred.isDone(releases.deferred)) yield* FiberMap.join(releases);\n }, Effect.ensuring(end));\n\n const retire = yield* Effect.cached(stop({ _tag: \"Retire\" }));\n\n yield* Effect.addFinalizer(() => (options.keep === true ? stop({ _tag: \"Keep\" }) : retire));\n yield* perform(started);\n\n return {\n browser: Effect.map(waitFor(state, waitTimeout, clock), (live) => live.value.opened.browser),\n use: leasing(state, apply, waitTimeout, now, clock),\n states: Stream.fromPubSubTake(events),\n rotate: apply({ _tag: \"Rotate\" }).pipe(\n Effect.flatMap(({ reply }) =>\n reply === undefined\n ? Effect.fail(retired())\n : Effect.map(\n waitFor(state, waitTimeout, clock, reply),\n (live) => live.value.opened.browser,\n ),\n ),\n ),\n retire,\n };\n});\n\n/** Supervise scoped generation values. Browser-only providers retain their existing void value. */\nexport function make<E, R, A = void>(\n options: Options<E, R, A>,\n): Effect.Effect<Supervisor<A>, never, Scope.Scope | Exclude<R, Scope.Scope>>;\n\nexport function make<E, R>(\n options: MakeOptions<E, R, never>,\n): Effect.Effect<Supervisor<void>, never, Scope.Scope | Exclude<R, Scope.Scope>>;\n\nexport function make<E, R, A>(options: MakeOptions<E, R, A>) {\n return makeScoped(options);\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-BAjRj7Xo.mjs","names":["make","Url.redactWithin","Lane.make"],"sources":["../src/internal/input/replies.ts","../src/internal/page/context.ts"],"sourcesContent":["/**\n * Bounded input replies owned by the page, including after an action is interrupted.\n * Canceling a caller cannot cancel a protocol command already sent. The next action waits for\n * those replies, while a stopped run releases only held keys or buttons whose release was never submitted.\n */\nimport { Context, Data, Effect } from \"effect\";\n\nimport { maximumSamples } from \"../../Motion.ts\";\n\nexport const capacity = 64;\n\nexport class InputFailure extends Data.TaggedError(\"InputFailure\")<{\n readonly cause: unknown;\n}> {}\n\nexport interface Run {\n /** A native call made by this operation: cancellation cannot cancel its actual reply. */\n readonly track: <A>(reply: Promise<A>) => Promise<A>;\n /** End ownership after the record and all this operation's native replies have settled. */\n readonly afterIdle: (ended: () => void) => void;\n /** Reserve a complete stroke, including its releases, before sending its first event. */\n readonly reserve: (commands: number) => Effect.Effect<void, InputFailure>;\n /** Admit every sample before a motion starts its published clock; ordinary input stays bounded separately. */\n readonly reserveMotion: (commands: number) => Effect.Effect<void, InputFailure>;\n readonly send: (command: () => Promise<unknown>) => Effect.Effect<void, InputFailure>;\n readonly down: (\n key: string,\n press: () => Promise<unknown>,\n release: () => Promise<unknown>,\n ) => Effect.Effect<void, InputFailure>;\n readonly up: (key: string) => Effect.Effect<void, InputFailure>;\n readonly drain: Effect.Effect<void, InputFailure>;\n /** Stop future input and submit missing releases without waiting indefinitely for replies. */\n readonly close: Effect.Effect<void>;\n}\n\n/** Native page calls join their operation's reply ownership, including script mutations. */\nexport const Current = Context.Reference<Run | undefined>(\"effect-browser/internal/input/Current\", {\n defaultValue: () => undefined,\n});\n\nexport const make = () => {\n const outstanding = new Set<Promise<void>>();\n\n // A timed-out action keeps capacity until its real replies arrive. Waiting for them sends\n // nothing, so cancellation here cannot leave a detached continuation that later types.\n const idle = Effect.gen(function* () {\n while (outstanding.size > 0) yield* Effect.promise(() => Promise.all(outstanding));\n });\n\n const begin = Effect.gen(function* () {\n yield* idle;\n const pending = new Set<Promise<void>>();\n const held: Array<{ readonly key: string; readonly release: () => Promise<unknown> }> = [];\n let failure: InputFailure | undefined;\n let reserved = 0;\n let closed = false;\n const observed = new WeakMap<Promise<unknown>, { input: boolean }>();\n const endings = new Set<() => void>();\n\n const track = <A>(response: Promise<A>, input = false): Promise<A> => {\n const existing = observed.get(response);\n\n if (existing !== undefined) {\n existing.input ||= input;\n\n return response;\n }\n const entry = { input };\n\n observed.set(response, entry);\n\n const reply = response\n .then(\n () => undefined,\n (cause: unknown) => {\n if (entry.input) failure ??= new InputFailure({ cause });\n },\n )\n .then(() => {\n pending.delete(reply);\n outstanding.delete(reply);\n if (pending.size === 0) {\n for (const end of endings) end();\n endings.clear();\n }\n });\n\n pending.add(reply);\n outstanding.add(reply);\n\n return response;\n };\n\n const requireOpen = Effect.suspend(() =>\n closed\n ? Effect.fail(new InputFailure({ cause: new Error(\"the input run has stopped\") }))\n : Effect.void,\n );\n\n const requireSuccess = Effect.suspend(() =>\n failure === undefined ? Effect.void : Effect.fail(failure),\n );\n\n const submit = (command: () => Promise<unknown>) => {\n if (reserved < 1) throw new Error(\"input must reserve capacity before dispatch\");\n reserved--;\n let response: Promise<unknown>;\n\n try {\n response = command();\n } catch (cause) {\n failure ??= new InputFailure({ cause });\n\n return;\n }\n\n void track(response, true);\n };\n\n const reserve = (commands: number, maximum: number, limit: number) =>\n Effect.gen(function* () {\n yield* requireOpen;\n yield* requireSuccess;\n if (!Number.isInteger(commands) || commands < 1 || commands > maximum)\n return yield* Effect.die(new Error(\"invalid input reservation\"));\n while (outstanding.size + reserved + commands > limit) {\n yield* Effect.promise(() => Promise.race(outstanding));\n yield* requireOpen;\n yield* requireSuccess;\n }\n reserved += commands;\n });\n\n const run: Run = {\n track,\n afterIdle: (end) => {\n if (pending.size === 0) end();\n else endings.add(end);\n },\n reserve: (commands) => reserve(commands, capacity, capacity),\n // A dense stroke cannot wait for replies midway without changing its published timing.\n // Its finite reservation also leaves room for the ordinary pool's already-owned releases.\n reserveMotion: (commands) => reserve(commands, maximumSamples, capacity + maximumSamples),\n send: (command) =>\n Effect.gen(function* () {\n yield* requireOpen;\n yield* requireSuccess;\n yield* Effect.sync(() => submit(command));\n yield* requireSuccess;\n }),\n down: (key, press, release) =>\n Effect.gen(function* () {\n yield* requireOpen;\n yield* requireSuccess;\n yield* Effect.sync(() => {\n held.push({ key, release });\n submit(press);\n });\n yield* requireSuccess;\n }),\n up: (key) =>\n Effect.gen(function* () {\n yield* requireOpen;\n yield* Effect.sync(() => {\n const index = held.findLastIndex((entry) => entry.key === key);\n const entry = held[index];\n\n if (entry === undefined) return;\n // Submission owns the release, even if its reply fails. Retrying an uncertain\n // release could run page handlers twice, so cleanup never sends it again.\n held.splice(index, 1);\n submit(entry.release);\n });\n yield* requireSuccess;\n }),\n drain: Effect.gen(function* () {\n while (pending.size > 0) yield* Effect.promise(() => Promise.all(pending));\n yield* requireSuccess;\n }),\n close: Effect.sync(() => {\n if (closed) return;\n closed = true;\n for (const entry of held.toReversed()) submit(entry.release);\n held.length = 0;\n reserved = 0;\n }),\n };\n\n return run;\n });\n\n /** `idle` lets an action wait, in its page's turn, for the page's earlier replies. */\n return { idle, begin };\n};\n","/**\n * What a page's parts share: the browser state they act on, the page's own lane, pointer and\n * clock, and how they call the browser and report its failures. The assembly in `page.ts` builds\n * one context per page.\n */\nimport {\n Clock,\n Context,\n Duration,\n Effect,\n Fiber,\n MutableRef,\n Option,\n Schema,\n type Scope,\n} from \"effect\";\nimport type { CDPSession, Page as PlaywrightPage } from \"playwright-core\";\n\nimport type { CaptureSource } from \"../../Browser.ts\";\nimport { BrowserError, Closed, Failed, type Reason, Timeout } from \"../../BrowserError.ts\";\nimport type { BrowserEvent } from \"../../BrowserEvent.ts\";\nimport type { InputGuard, Point } from \"../../Page.ts\";\nimport type { Gate } from \"../input/gate.ts\";\nimport { Current } from \"../input/replies.ts\";\nimport type * as BrowserClock from \"../pictures/clock.ts\";\nimport * as Lane from \"./lane.ts\";\nimport type { Openings } from \"./openings.ts\";\nimport * as Url from \"./url.ts\";\n\n/** Why a page is gone. */\nexport type ClosedCause = Closed[\"cause\"];\n\n/** What every page of a browser shares, from its options. */\nexport interface Settings {\n readonly actionTimeout: Duration.Duration;\n readonly policyTimeout: Duration.Duration;\n readonly navigationTimeout: Duration.Duration;\n /** How long screencast frames stay in `recentFrames`, measured back from the newest. */\n readonly frameHistory: Duration.Duration;\n readonly guard: InputGuard | undefined;\n}\n\nexport interface MakeOptions {\n /** The page's CDP target id, which is also its main frame's id. */\n readonly id: string;\n /** The id of the browser's session, which its frames carry. */\n readonly session: string;\n /** This tracking connection, distinct from the provider session and capture socket. */\n readonly connection: string;\n /** The page's address when the browser began tracking it. */\n readonly url: string;\n readonly playwright: PlaywrightPage;\n readonly cdp: CDPSession;\n /** A call's reply, or a failure as for a closed page once the browser is lost first. */\n readonly untilLost: <A>(reply: Promise<A>) => Promise<A>;\n readonly settings: Settings;\n readonly clock: Clock.Clock;\n /** Browser-wide input authority; direct internal page fixtures need not provide one. */\n readonly inputGate?: Gate | undefined;\n /** The browser's epoch mapping: its first capture measures it, and later ones renew it. */\n readonly mapping: BrowserClock.Mapping;\n readonly publish: (event: BrowserEvent) => number;\n /** This page's retained events, oldest first. */\n readonly recentEvents: Effect.Effect<ReadonlyArray<BrowserEvent>>;\n /** Registration of the actual popups this page's current input opened. */\n readonly openings: Openings;\n /** Succeeds once the page's own session holds focus emulation, which keeps it painting behind. */\n readonly focused: Effect.Effect<void, BrowserError>;\n /** Succeeds once the page's own session has the Page domain on, so it sees every later commit. */\n readonly paging: (operation: string) => Effect.Effect<void, BrowserError>;\n /** Why the page is gone, once it is: its browser's loss, else its own close or crash. */\n readonly closedBy: () => ClosedCause;\n /** Where the page's screencast runs, if not on its own session. */\n readonly capture?: CaptureSource | undefined;\n}\n\nconst messageOf = (cause: unknown): string =>\n cause instanceof Error ? cause.message : typeof cause === \"string\" ? cause : \"unknown error\";\n\nconst closedPattern =\n /has been closed|Target closed|Session closed|browser has disconnected|Target page, context or browser/i;\n\n/**\n * Map a Playwright or protocol failure to a reason, `Closed` with `closed` as its cause for a page\n * or browser that is gone. A call that gives Playwright a timeout passes the same bound, so its\n * `Timeout` reports it; without one, Playwright's own message stays.\n */\nexport const reasonOf = (\n cause: unknown,\n timeoutMillis?: number,\n closed: ClosedCause = \"connection\",\n): Reason => {\n const message = messageOf(cause);\n\n if (closedPattern.test(message)) return new Closed({ cause: closed });\n if (cause instanceof Error && cause.name === \"TimeoutError\" && timeoutMillis !== undefined)\n return new Timeout({ millis: timeoutMillis });\n const line = message.split(\"\\n\")[0] ?? message;\n\n return new Failed({ detail: Url.redactWithin(line.replace(/^[\\w.]+: /, \"\")) });\n};\n\n/**\n * One Playwright or protocol call, failing undispatched. A closed page says why it is gone as the\n * browser knows then: the library's own calls fail with the browser's loss, and Playwright fails\n * its calls on a dropped connection after reporting the context closed.\n */\nexport const call = <A>(\n operation: string,\n run: () => Promise<A>,\n closedBy: () => ClosedCause,\n timeoutMillis?: number,\n) =>\n Effect.tryPromise({\n try: run,\n catch: (cause) => undispatched(operation, reasonOf(cause, timeoutMillis, closedBy())),\n });\n\nexport const contextGone = (error: BrowserError) =>\n error.reason._tag === \"Failed\" &&\n /Cannot find context|Execution context was destroyed|__effectBrowser|Inspected target navigated/i.test(\n error.reason.detail,\n );\n\n/**\n * What a page operation spent on the page's own protocol session: its calls, the bytes of their\n * parameters and results, and how long at least one of them awaited its reply. An operation inside\n * another counts toward both.\n */\ninterface Cost {\n readonly enclosing: Cost | undefined;\n calls: number;\n bytesOut: number;\n bytesIn: number;\n waitedMillis: number;\n awaiting: number;\n awaitingSince: number;\n}\n\n/** The cost of the page operation the current fiber runs, if any. */\nconst CurrentCost = Context.Reference<Cost | undefined>(\n \"effect-browser/internal/page/CurrentCost\",\n {\n defaultValue: () => undefined,\n },\n);\n\n/** Track the promise returned to the action, after tracing wraps it, so input counts once. */\nconst track = <A>(reply: Promise<A>) => Fiber.getCurrent()?.getRef(Current)?.track(reply) ?? reply;\n\n// A message's size on the wire, give or take its envelope.\nconst sizeOf = (value: unknown) =>\n value === undefined ? 0 : Buffer.byteLength(JSON.stringify(value));\n\n/** A failure of `operation` before any of its input reached the browser. */\nexport const undispatched = (operation: string, reason: Reason) =>\n new BrowserError({ operation, reason, dispatched: false });\n\nexport const failWith = (operation: string, reason: Reason) =>\n Effect.fail(undispatched(operation, reason));\n\nexport const decodeWith =\n <A>(operation: string, schema: Schema.Codec<A, unknown>) =>\n (value: unknown) =>\n Schema.decodeUnknownEffect(schema)(value).pipe(\n Effect.mapError((error) => undispatched(operation, new Failed({ detail: error.message }))),\n );\n\nexport const make = (options: MakeOptions, scope: Scope.Scope) => {\n const { id, clock } = options;\n const now = () => Number(clock.monotonicTimeNanosUnsafe()) / 1e6;\n // Deadlines and pacing guard the page's lane, so page operations run on the owner's clock; a\n // caller's clock, such as a TestClock, cannot stall or stretch them.\n const owned = Effect.provideService(Clock.Clock, clock);\n\n // This page's spans name it and report what the operation cost on the protocol. Fine-grained\n // ones carry a level below the default Info, so an application keeps only the coarse ones by\n // raising `Tracer.MinimumTraceLevel`.\n const span =\n (name: string, attributes: Record<string, unknown> = {}, level?: \"Debug\" | \"Trace\") =>\n <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n Effect.gen(function* () {\n const cost: Cost = {\n enclosing: yield* CurrentCost,\n calls: 0,\n bytesOut: 0,\n bytesIn: 0,\n waitedMillis: 0,\n awaiting: 0,\n awaitingSince: 0,\n };\n\n return yield* effect.pipe(\n Effect.provideService(CurrentCost, cost),\n Effect.ensuring(\n Effect.suspend(() =>\n Effect.annotateCurrentSpan({\n calls: cost.calls,\n bytesOut: cost.bytesOut,\n bytesIn: cost.bytesIn,\n waitedMillis: Math.round(cost.waitedMillis * 10) / 10,\n }),\n ),\n ),\n );\n }).pipe(\n Effect.withSpan(\n name,\n { attributes: { page: id, ...attributes }, ...(level === undefined ? {} : { level }) },\n { captureStackTrace: false },\n ),\n );\n\n // Every call on the page's own protocol session, counted into the operation that sends it and\n // the operations around that one. It is looked up when the call is sent, so input pipelined\n // from inside an operation counts toward it too.\n const send: CDPSession[\"send\"] = (method, params) => {\n const cost = Fiber.getCurrent()?.getRef(CurrentCost);\n const sentAt = now();\n const bytesOut = sizeOf(params);\n\n for (let each = cost; each !== undefined; each = each.enclosing) {\n each.calls++;\n each.bytesOut += bytesOut;\n if (each.awaiting++ === 0) each.awaitingSince = sentAt;\n }\n const reply = options.untilLost(options.cdp.send(method, params));\n\n if (cost === undefined) return track(reply);\n\n const settle = (bytesIn: number) => {\n const at = now();\n\n for (let each: Cost | undefined = cost; each !== undefined; each = each.enclosing) {\n each.bytesIn += bytesIn;\n if (--each.awaiting === 0) each.waitedMillis += at - each.awaitingSince;\n }\n };\n\n return track(\n reply.then(\n (result) => {\n settle(sizeOf(result));\n\n return result;\n },\n (cause: unknown) => {\n settle(0);\n\n return Promise.reject(cause);\n },\n ),\n );\n };\n\n // Every protocol or Playwright call. Errors are undispatched here; `perform` marks them\n // dispatched once input has gone out.\n const native = <A>(operation: string, run: () => Promise<A>, timeoutMillis?: number) =>\n call(operation, () => track(run()), options.closedBy, timeoutMillis);\n\n /** Fail with `Timeout` once `duration` has passed, the action timeout unless another is given. */\n const within =\n (operation: string, duration: Duration.Input = options.settings.actionTimeout) =>\n <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n Effect.timeoutOrElse(effect, {\n duration,\n orElse: () => failWith(operation, new Timeout({ millis: Duration.toMillis(duration) })),\n });\n\n // Stop a navigation whose bounded wait failed. The stop and original mutation keep their\n // actual replies owned; this cleanup does not turn an unanswered acknowledgement into success.\n const stopLoading = native(\"stopLoading\", () => send(\"Page.stopLoading\")).pipe(\n within(\"stopLoading\", options.settings.navigationTimeout),\n Effect.ignore,\n );\n\n // The latest submitted input or page change. A read that must follow it waits for the action in\n // flight, so only paint from after its latest input is current. An action ends after its input\n // was handled, so if that input changed the page, newer paint follows; a lost final paint is\n // bounded by recency instead. Paint from before the current document began, when the page's own\n // session saw the main frame commit it, shows a page the tab has left, so no read reuses it,\n // whatever it asks.\n const activity = { inputAt: 0, documentAt: Number.NEGATIVE_INFINITY };\n\n const noteInput = () => {\n activity.inputAt = Math.max(activity.inputAt, now());\n };\n\n const lane = Lane.make({\n now,\n actionTimeout: options.settings.actionTimeout,\n documentAt: () => activity.documentAt,\n gone: (operation) => undispatched(operation, new Closed({ cause: options.closedBy() })),\n scope,\n inputGate: options.inputGate,\n });\n\n // Where this page's latest move left its pointer, which is where its next plain glide starts and\n // where a held button is released. Its lane orders the page's input, and Chromium keeps a\n // pointer per page too.\n const pointer = MutableRef.make(Option.none<Point>());\n\n // Named, so that the declarations of what holds it need not spell out Playwright's protocol types.\n const protocol: Pick<CDPSession, \"send\"> = { send };\n\n return {\n ...options,\n lane,\n pointer,\n now,\n owned,\n span,\n protocol,\n native,\n within,\n stopLoading,\n activity,\n noteInput,\n };\n};\n\nexport type PageContext = ReturnType<typeof make>;\n"],"mappings":"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"}
|