effect-browser 0.2.0-beta.9 → 0.3.0-beta.10
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 +849 -1161
- package/dist/Browser-S4kvpmqa.mjs +605 -0
- package/dist/Browser-S4kvpmqa.mjs.map +1 -0
- package/dist/Browser.d.mts +127 -3
- package/dist/Browser.mjs +2 -22
- package/dist/BrowserError-Coy7EW1N.d.mts +140 -0
- package/dist/BrowserError.d.mts +2 -0
- package/dist/BrowserError.mjs +211 -0
- package/dist/BrowserError.mjs.map +1 -0
- package/dist/BrowserEvent-BRu2juEz.d.mts +279 -0
- package/dist/BrowserEvent.d.mts +2 -0
- package/dist/BrowserEvent.mjs +297 -0
- package/dist/BrowserEvent.mjs.map +1 -0
- package/dist/Cdp.d.mts +32 -0
- package/dist/Cdp.mjs +61 -0
- package/dist/Cdp.mjs.map +1 -0
- package/dist/Change-DNvztNLu.mjs +138 -0
- package/dist/Change-DNvztNLu.mjs.map +1 -0
- package/dist/Change-iMlcuzVD.d.mts +71 -0
- package/dist/Change.d.mts +2 -0
- package/dist/Change.mjs +2 -0
- package/dist/Chromium.d.mts +29 -81
- package/dist/Chromium.mjs +57 -392
- package/dist/Chromium.mjs.map +1 -1
- package/dist/Expect.d.mts +62 -0
- package/dist/Expect.mjs +114 -0
- package/dist/Expect.mjs.map +1 -0
- package/dist/Frame-BERmf_gM.d.mts +117 -0
- package/dist/Frame.d.mts +2 -0
- package/dist/Frame.mjs +123 -0
- package/dist/Frame.mjs.map +1 -0
- package/dist/Moment.d.mts +2 -0
- package/dist/Moment.mjs +288 -0
- package/dist/Moment.mjs.map +1 -0
- package/dist/Motion.d.mts +40 -0
- package/dist/Motion.mjs +122 -0
- package/dist/Motion.mjs.map +1 -0
- package/dist/Page-B5cjaUp5.mjs +618 -0
- package/dist/Page-B5cjaUp5.mjs.map +1 -0
- package/dist/Page-BlPjfibv.d.mts +595 -0
- package/dist/Page.d.mts +2 -0
- package/dist/Page.mjs +2 -0
- package/dist/Plan-BI8XGvDu.d.mts +209 -0
- package/dist/Plan-D1wrJVs8.mjs +508 -0
- package/dist/Plan-D1wrJVs8.mjs.map +1 -0
- package/dist/Plan.d.mts +2 -3
- package/dist/Plan.mjs +2 -2
- package/dist/Policy.d.mts +76 -0
- package/dist/Policy.mjs +237 -0
- package/dist/Policy.mjs.map +1 -0
- package/dist/Presentation.d.mts +48 -0
- package/dist/Presentation.mjs +117 -0
- package/dist/Presentation.mjs.map +1 -0
- package/dist/Snapshot-B34hZ4Jl.d.mts +68 -0
- package/dist/Snapshot.d.mts +2 -0
- package/dist/Snapshot.mjs +79 -0
- package/dist/Snapshot.mjs.map +1 -0
- package/dist/Stage.d.mts +64 -0
- package/dist/Stage.mjs +237 -0
- package/dist/Stage.mjs.map +1 -0
- package/dist/Supervisor-CYWFK3vM.d.mts +280 -0
- package/dist/Supervisor-TNKNOVzu.mjs +599 -0
- package/dist/Supervisor-TNKNOVzu.mjs.map +1 -0
- package/dist/Supervisor.d.mts +2 -0
- package/dist/Supervisor.mjs +2 -0
- package/dist/context-B6xr8nVi.mjs +261 -0
- package/dist/context-B6xr8nVi.mjs.map +1 -0
- package/dist/index.d.mts +17 -14
- package/dist/index.mjs +18 -13
- package/dist/match.inpage-xOe9LNO0.mjs +48 -0
- package/dist/match.inpage-xOe9LNO0.mjs.map +1 -0
- package/dist/page-B8tUQELg.mjs +5073 -0
- package/dist/page-B8tUQELg.mjs.map +1 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/dist/url-Cd04Okid.mjs +264 -0
- package/dist/url-Cd04Okid.mjs.map +1 -0
- package/package.json +96 -61
- package/src/Browser.ts +666 -0
- package/src/BrowserError.ts +234 -0
- package/src/BrowserEvent.ts +296 -0
- package/src/Cdp.ts +101 -0
- package/src/Change.ts +88 -0
- package/src/Chromium.ts +102 -0
- package/src/Expect.ts +180 -0
- package/src/Frame.ts +130 -0
- package/src/Moment.ts +479 -0
- package/src/Motion.ts +166 -0
- package/src/Page.ts +522 -0
- package/src/Plan.ts +663 -0
- package/src/Policy.ts +325 -0
- package/src/Presentation.ts +195 -0
- package/src/Snapshot.ts +89 -0
- package/src/Stage.ts +467 -0
- package/src/Supervisor.ts +599 -0
- package/src/index.ts +20 -0
- package/src/internal/input/actions.ts +610 -0
- package/src/internal/input/dispatch.ts +161 -0
- package/src/internal/input/edit.inpage.ts +162 -0
- package/src/internal/input/evidence.inpage.ts +164 -0
- package/src/internal/input/gate.ts +224 -0
- package/src/internal/input/guard.inpage.ts +605 -0
- package/src/internal/input/guard.ts +184 -0
- package/src/internal/input/keyboard.ts +112 -0
- package/src/internal/input/keys.ts +127 -0
- package/src/internal/input/perform.ts +376 -0
- package/src/internal/input/pointer.ts +153 -0
- package/src/internal/input/replies.ts +195 -0
- package/src/internal/input/settle.ts +50 -0
- package/src/internal/input/style.ts +186 -0
- package/src/internal/input/targets.inpage.ts +293 -0
- package/src/internal/input/targets.ts +148 -0
- package/src/internal/page/bridge.ts +386 -0
- package/src/internal/page/context.ts +312 -0
- package/src/internal/page/lane.ts +311 -0
- package/src/internal/page/navigation.ts +183 -0
- package/src/internal/page/openings.ts +87 -0
- package/src/internal/page/page.ts +165 -0
- package/src/internal/page/url.ts +100 -0
- package/src/internal/page/viewport.ts +43 -0
- package/src/internal/pictures/capture.ts +776 -0
- package/src/internal/pictures/clock.ts +141 -0
- package/src/internal/pictures/counts.ts +92 -0
- package/src/internal/pictures/pictures.ts +520 -0
- package/src/internal/pictures/transport.ts +242 -0
- package/src/internal/reading/choose.ts +100 -0
- package/src/internal/reading/context.inpage.ts +201 -0
- package/src/internal/reading/controls.inpage.ts +158 -0
- package/src/internal/reading/expect.inpage.ts +70 -0
- package/src/internal/reading/match.inpage.ts +92 -0
- package/src/internal/reading/names.inpage.ts +306 -0
- package/src/internal/reading/outline.inpage.ts +260 -0
- package/src/internal/reading/reading.ts +223 -0
- package/src/internal/reading/ready.inpage.ts +164 -0
- package/src/internal/reading/ready.ts +111 -0
- package/src/internal/reading/subjects.inpage.ts +188 -0
- package/src/internal/reading/text.inpage.ts +135 -0
- package/src/internal/reading/walk.inpage.ts +220 -0
- package/src/internal/supervisor/lifecycle.ts +416 -0
- package/src/internal/timeline/changes.inpage.ts +216 -0
- package/src/internal/timeline/changes.ts +100 -0
- package/src/internal/timeline/events.ts +94 -0
- package/src/internal/timeline/fold.inpage.ts +123 -0
- package/src/internal/timeline/history.inpage.ts +229 -0
- package/src/internal/timeline/marks.inpage.ts +207 -0
- package/src/internal/timeline/record.inpage.ts +133 -0
- package/src/internal/timeline/sight.inpage.ts +122 -0
- package/src/internal/timeline/window.ts +96 -0
- package/src/internal/timeline/words.ts +65 -0
- package/dist/Bootstrap-B9UUXsvF.d.mts +0 -183
- package/dist/Bootstrap-CeQOWBy6.mjs +0 -189
- package/dist/Bootstrap-CeQOWBy6.mjs.map +0 -1
- package/dist/Bootstrap.d.mts +0 -3
- package/dist/Bootstrap.mjs +0 -2
- package/dist/Browser-BF9_sORP.d.mts +0 -388
- package/dist/Browser.mjs.map +0 -1
- package/dist/BrowserData-CPIIIHol.d.mts +0 -585
- package/dist/BrowserData.d.mts +0 -3
- package/dist/BrowserData.mjs +0 -695
- package/dist/BrowserData.mjs.map +0 -1
- package/dist/BrowserRuntime-B6nT1G4X.d.mts +0 -148
- package/dist/BrowserRuntime-C1r2aSRK.mjs +0 -6820
- package/dist/BrowserRuntime-C1r2aSRK.mjs.map +0 -1
- package/dist/BrowserRuntime.d.mts +0 -3
- package/dist/BrowserRuntime.mjs +0 -3
- package/dist/Capture.d.mts +0 -56
- package/dist/Capture.mjs +0 -678
- package/dist/Capture.mjs.map +0 -1
- package/dist/CaptureData-CYriZHX1.mjs +0 -201
- package/dist/CaptureData-CYriZHX1.mjs.map +0 -1
- package/dist/CaptureData.d.mts +0 -219
- package/dist/CaptureData.mjs +0 -2
- package/dist/Errors.d.mts +0 -158
- package/dist/Errors.mjs +0 -207
- package/dist/Errors.mjs.map +0 -1
- package/dist/Images-yCG9BmRU.mjs +0 -76
- package/dist/Images-yCG9BmRU.mjs.map +0 -1
- package/dist/OperationOptions-DAeRS6O9.mjs +0 -55
- package/dist/OperationOptions-DAeRS6O9.mjs.map +0 -1
- package/dist/PageControl.d.mts +0 -15
- package/dist/PageControl.mjs +0 -34
- package/dist/PageControl.mjs.map +0 -1
- package/dist/PageRegistry-B3q9DS3g.mjs +0 -164
- package/dist/PageRegistry-B3q9DS3g.mjs.map +0 -1
- package/dist/Plan-Dyxu2q8C.mjs +0 -543
- package/dist/Plan-Dyxu2q8C.mjs.map +0 -1
- package/dist/PlanData-B668RxbQ.d.mts +0 -4831
- package/dist/PlanData.d.mts +0 -3
- package/dist/PlanData.mjs +0 -268
- package/dist/PlanData.mjs.map +0 -1
- package/dist/PlanInput-BJcPPncs.mjs +0 -75
- package/dist/PlanInput-BJcPPncs.mjs.map +0 -1
- package/dist/PublicSession-DCSMMqOj.mjs +0 -5602
- package/dist/PublicSession-DCSMMqOj.mjs.map +0 -1
- package/dist/Testing.d.mts +0 -479
- package/dist/Testing.mjs +0 -2147
- package/dist/Testing.mjs.map +0 -1
- package/dist/Timeline-fV22Xk-S.d.mts +0 -29
- package/dist/Timeline.d.mts +0 -4
- package/dist/Timeline.mjs +0 -20
- package/dist/Timeline.mjs.map +0 -1
- package/dist/TimelineData-BsOn-YGZ.d.mts +0 -3818
- package/dist/TimelineData.d.mts +0 -3
- package/dist/TimelineData.mjs +0 -482
- package/dist/TimelineData.mjs.map +0 -1
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { BrowserError, Reasons } from "./Errors.mjs";
|
|
2
|
-
import { Deferred, Effect } from "effect";
|
|
3
|
-
//#region src/internal/browser/PageRegistry.ts
|
|
4
|
-
/**
|
|
5
|
-
* The session's registered pages at their connection generations. Callers read the records; only
|
|
6
|
-
* these transitions change them.
|
|
7
|
-
*/
|
|
8
|
-
const makePageRegistry = () => {
|
|
9
|
-
const pages = /* @__PURE__ */ new Map();
|
|
10
|
-
const owned = /* @__PURE__ */ new WeakMap();
|
|
11
|
-
const state = (record) => {
|
|
12
|
-
const found = owned.get(record);
|
|
13
|
-
if (found === void 0) throw new TypeError("Page record belongs to another registry");
|
|
14
|
-
return found;
|
|
15
|
-
};
|
|
16
|
-
return {
|
|
17
|
-
get: (pageId) => pages.get(pageId),
|
|
18
|
-
records: () => [...pages.values()],
|
|
19
|
-
/** Registers a page at a new generation, replacing any record of an earlier one. */
|
|
20
|
-
add: (init) => {
|
|
21
|
-
const record = {
|
|
22
|
-
identity: init.identity,
|
|
23
|
-
admission: init.admission,
|
|
24
|
-
info: init.info,
|
|
25
|
-
frames: /* @__PURE__ */ new Map(),
|
|
26
|
-
phase: init.paused ? "paused" : "open",
|
|
27
|
-
containment: { _tag: "NotRequired" },
|
|
28
|
-
store: init.store,
|
|
29
|
-
retirement: init.retirement,
|
|
30
|
-
get terminal() {
|
|
31
|
-
return init.terminal();
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
owned.set(record, record);
|
|
35
|
-
pages.set(init.info.pageId, record);
|
|
36
|
-
return record;
|
|
37
|
-
},
|
|
38
|
-
/** A popup/dialog policy holds an open page for its operator. */
|
|
39
|
-
pause: (pageId) => {
|
|
40
|
-
const page = pages.get(pageId);
|
|
41
|
-
if (page !== void 0 && page.phase === "open") page.phase = "paused";
|
|
42
|
-
},
|
|
43
|
-
/** The page is being closed: its issued authority refuses new work. */
|
|
44
|
-
closing: (pageId) => {
|
|
45
|
-
const page = pages.get(pageId);
|
|
46
|
-
if (page !== void 0 && page.phase !== "closed") page.phase = "closing";
|
|
47
|
-
},
|
|
48
|
-
/** The page closed: it settles its closure attempt and leaves the registry. */
|
|
49
|
-
closed: (pageId) => {
|
|
50
|
-
const page = pages.get(pageId);
|
|
51
|
-
if (page === void 0) return;
|
|
52
|
-
page.phase = "closed";
|
|
53
|
-
if (page.attempt !== void 0) Deferred.doneUnsafe(page.attempt, Effect.succeed(true));
|
|
54
|
-
pages.delete(pageId);
|
|
55
|
-
},
|
|
56
|
-
/** Records how an unknown outcome on this page was contained. */
|
|
57
|
-
contain: (record, containment) => {
|
|
58
|
-
state(record).containment = containment;
|
|
59
|
-
},
|
|
60
|
-
/** The native closure now in flight for this page. */
|
|
61
|
-
attempting: (record, attempt) => {
|
|
62
|
-
state(record).attempt = attempt;
|
|
63
|
-
},
|
|
64
|
-
/** The page's record of one frame, registered on first use. */
|
|
65
|
-
frame: (record, frameId) => {
|
|
66
|
-
const page = state(record);
|
|
67
|
-
const existing = page.frames.get(frameId);
|
|
68
|
-
if (existing !== void 0) return existing;
|
|
69
|
-
const frame = { detached: false };
|
|
70
|
-
page.frames.set(frameId, frame);
|
|
71
|
-
return frame;
|
|
72
|
-
},
|
|
73
|
-
/** A frame left its page: Frames issued for it are refused from now on. */
|
|
74
|
-
detachFrame: (pageId, frameId) => {
|
|
75
|
-
const page = pages.get(pageId);
|
|
76
|
-
const frame = page?.frames.get(frameId);
|
|
77
|
-
if (frame !== void 0) frame.detached = true;
|
|
78
|
-
page?.frames.delete(frameId);
|
|
79
|
-
},
|
|
80
|
-
clear: () => {
|
|
81
|
-
pages.clear();
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
};
|
|
85
|
-
const issued = /* @__PURE__ */ new WeakMap();
|
|
86
|
-
const canonical = /* @__PURE__ */ new WeakMap();
|
|
87
|
-
/** Registers a session's own capture parent under the session object itself. */
|
|
88
|
-
const issueSession = (session, capture) => {
|
|
89
|
-
issued.set(session, {
|
|
90
|
-
_tag: "Session",
|
|
91
|
-
capture
|
|
92
|
-
});
|
|
93
|
-
};
|
|
94
|
-
/** The canonical Page for `record`: built by `make` and registered the first time only. */
|
|
95
|
-
const issuePage = (record, make, authority) => {
|
|
96
|
-
const existing = canonical.get(record);
|
|
97
|
-
if (existing !== void 0) return existing;
|
|
98
|
-
const page = make();
|
|
99
|
-
const { controls, capture, pageControl } = authority();
|
|
100
|
-
canonical.set(record, page);
|
|
101
|
-
issued.set(page, {
|
|
102
|
-
_tag: "Page",
|
|
103
|
-
record,
|
|
104
|
-
controls,
|
|
105
|
-
capture,
|
|
106
|
-
pageControl: {
|
|
107
|
-
port: pageControl.port,
|
|
108
|
-
page: Object.freeze({ ...pageControl.page })
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
return page;
|
|
112
|
-
};
|
|
113
|
-
/** An issued Frame keeps its own exact controls and the owner of the session that issued it. */
|
|
114
|
-
const issueFrame = (frame, owner, controls) => {
|
|
115
|
-
issued.set(frame, {
|
|
116
|
-
_tag: "Frame",
|
|
117
|
-
owner,
|
|
118
|
-
controls
|
|
119
|
-
});
|
|
120
|
-
};
|
|
121
|
-
const sessionOwner = (session) => {
|
|
122
|
-
const entry = issued.get(session);
|
|
123
|
-
return entry?._tag === "Session" ? entry.capture.owner : void 0;
|
|
124
|
-
};
|
|
125
|
-
/** The issued Page `page` is, if this exact object was issued by the session owning `owner`. */
|
|
126
|
-
const issuedPageOf = (page, owner) => {
|
|
127
|
-
const entry = issued.get(page);
|
|
128
|
-
return entry?._tag === "Page" && entry.capture.owner === owner ? entry : void 0;
|
|
129
|
-
};
|
|
130
|
-
/** Capture binds only to original issued Page authority; a session association is insufficient. */
|
|
131
|
-
const capturePageParent = (page) => {
|
|
132
|
-
const entry = issued.get(page);
|
|
133
|
-
return entry?._tag === "Page" ? entry.capture : void 0;
|
|
134
|
-
};
|
|
135
|
-
/** The page control an issued Page carries. */
|
|
136
|
-
const pageControl = (page) => {
|
|
137
|
-
const entry = issued.get(page);
|
|
138
|
-
return entry?._tag === "Page" ? entry.pageControl : void 0;
|
|
139
|
-
};
|
|
140
|
-
const unregistered = (operation) => Effect.fail(BrowserError.make({
|
|
141
|
-
operation,
|
|
142
|
-
reason: Reasons.UnregisteredSession.make({}),
|
|
143
|
-
outcome: "undispatched"
|
|
144
|
-
}));
|
|
145
|
-
/** Provider bridges borrow the exact issued page on this session's original owner. */
|
|
146
|
-
const resolvePageControlsForSession = (session, page, operation = "target") => Effect.suspend(() => {
|
|
147
|
-
const owner = sessionOwner(session);
|
|
148
|
-
const entry = owner === void 0 ? void 0 : issuedPageOf(page, owner);
|
|
149
|
-
return entry === void 0 ? unregistered(operation) : entry.controls.validate(operation).pipe(Effect.as(entry.controls));
|
|
150
|
-
});
|
|
151
|
-
/**
|
|
152
|
-
* Tools borrow an exact issued Page, or an exact Frame one of its Pages issued, on this session's
|
|
153
|
-
* original owner. Capture, page control and provider transfers stay Page-only.
|
|
154
|
-
*/
|
|
155
|
-
const resolveTargetControlsForSession = (session, target, operation = "target") => Effect.suspend(() => {
|
|
156
|
-
const entry = issued.get(target);
|
|
157
|
-
if (entry?._tag !== "Frame") return resolvePageControlsForSession(session, target, operation);
|
|
158
|
-
if (sessionOwner(session) !== entry.owner) return unregistered(operation);
|
|
159
|
-
return entry.controls.validate(operation).pipe(Effect.as(entry.controls));
|
|
160
|
-
});
|
|
161
|
-
//#endregion
|
|
162
|
-
export { issuedPageOf as a, resolvePageControlsForSession as c, issueSession as i, resolveTargetControlsForSession as l, issueFrame as n, makePageRegistry as o, issuePage as r, pageControl as s, capturePageParent as t };
|
|
163
|
-
|
|
164
|
-
//# sourceMappingURL=PageRegistry-B3q9DS3g.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PageRegistry-B3q9DS3g.mjs","names":[],"sources":["../src/internal/browser/PageRegistry.ts"],"sourcesContent":["import { Deferred, Effect } from \"effect\";\n\nimport type { OperationOptions, Page, PageStatus } from \"../../Browser.ts\";\nimport type { PageExecutionState, PageInfo, PageSuspension, Target } from \"../../BrowserData.ts\";\nimport { BrowserError, Reasons, type BrowserOperation } from \"../../Errors.ts\";\nimport type { Terminal } from \"../../TimelineData.ts\";\nimport type { makeRetirement } from \"../timeline/Retirement.ts\";\nimport type { makeStore } from \"../timeline/Store.ts\";\nimport type { AdmissionLane } from \"./Admission.ts\";\nimport type { CaptureParent, PageCaptureParent } from \"./Association.ts\";\nimport type { Owner } from \"./Owner.ts\";\nimport type { PageControls } from \"./Session.ts\";\n\n/** One frame of a registered page. Frames issued for a detached one are refused. */\nexport interface FrameRecord {\n readonly detached: boolean;\n}\n\n/** The session's record of one registered page at one connection generation. */\nexport interface PageRecord {\n readonly identity: Target;\n readonly admission: AdmissionLane;\n readonly info: PageInfo;\n readonly frames: ReadonlyMap<string, FrameRecord>;\n readonly phase: \"open\" | \"paused\" | \"closing\" | \"closed\";\n readonly containment: PageStatus[\"containment\"];\n readonly store: ReturnType<typeof makeStore>;\n readonly terminal: Terminal | null;\n readonly retirement: ReturnType<typeof makeRetirement>;\n /** The native closure in flight for this page, settled true once it closed. */\n readonly attempt?: Deferred.Deferred<boolean>;\n}\n\ninterface FrameState {\n detached: boolean;\n}\n\ninterface RecordState {\n readonly identity: Target;\n readonly admission: AdmissionLane;\n readonly info: PageInfo;\n readonly frames: Map<string, FrameState>;\n phase: PageRecord[\"phase\"];\n containment: PageStatus[\"containment\"];\n readonly store: ReturnType<typeof makeStore>;\n readonly terminal: Terminal | null;\n readonly retirement: ReturnType<typeof makeRetirement>;\n attempt?: Deferred.Deferred<boolean>;\n}\n\n/**\n * The session's registered pages at their connection generations. Callers read the records; only\n * these transitions change them.\n */\nexport const makePageRegistry = () => {\n const pages = new Map<string, RecordState>();\n // Every record this registry made, by identity, including ones it no longer lists.\n const owned = new WeakMap<PageRecord, RecordState>();\n\n const state = (record: PageRecord): RecordState => {\n const found = owned.get(record);\n\n if (found === undefined) throw new TypeError(\"Page record belongs to another registry\");\n\n return found;\n };\n\n return {\n get: (pageId: string): PageRecord | undefined => pages.get(pageId),\n records: (): ReadonlyArray<PageRecord> => [...pages.values()],\n /** Registers a page at a new generation, replacing any record of an earlier one. */\n add: (init: {\n readonly identity: Target;\n readonly admission: AdmissionLane;\n readonly info: PageInfo;\n readonly paused: boolean;\n readonly store: ReturnType<typeof makeStore>;\n readonly retirement: ReturnType<typeof makeRetirement>;\n readonly terminal: () => Terminal | null;\n }): PageRecord => {\n const record: RecordState = {\n identity: init.identity,\n admission: init.admission,\n info: init.info,\n frames: new Map(),\n phase: init.paused ? \"paused\" : \"open\",\n containment: { _tag: \"NotRequired\" },\n store: init.store,\n retirement: init.retirement,\n get terminal() {\n return init.terminal();\n },\n };\n\n owned.set(record, record);\n pages.set(init.info.pageId, record);\n\n return record;\n },\n /** A popup/dialog policy holds an open page for its operator. */\n pause: (pageId: string) => {\n const page = pages.get(pageId);\n\n if (page !== undefined && page.phase === \"open\") page.phase = \"paused\";\n },\n /** The page is being closed: its issued authority refuses new work. */\n closing: (pageId: string) => {\n const page = pages.get(pageId);\n\n if (page !== undefined && page.phase !== \"closed\") page.phase = \"closing\";\n },\n /** The page closed: it settles its closure attempt and leaves the registry. */\n closed: (pageId: string) => {\n const page = pages.get(pageId);\n\n if (page === undefined) return;\n page.phase = \"closed\";\n if (page.attempt !== undefined) Deferred.doneUnsafe(page.attempt, Effect.succeed(true));\n pages.delete(pageId);\n },\n /** Records how an unknown outcome on this page was contained. */\n contain: (record: PageRecord, containment: PageStatus[\"containment\"]) => {\n state(record).containment = containment;\n },\n /** The native closure now in flight for this page. */\n attempting: (record: PageRecord, attempt: Deferred.Deferred<boolean>) => {\n state(record).attempt = attempt;\n },\n /** The page's record of one frame, registered on first use. */\n frame: (record: PageRecord, frameId: string): FrameRecord => {\n const page = state(record);\n const existing = page.frames.get(frameId);\n\n if (existing !== undefined) return existing;\n const frame: FrameState = { detached: false };\n\n page.frames.set(frameId, frame);\n\n return frame;\n },\n /** A frame left its page: Frames issued for it are refused from now on. */\n detachFrame: (pageId: string, frameId: string) => {\n const page = pages.get(pageId);\n const frame = page?.frames.get(frameId);\n\n if (frame !== undefined) frame.detached = true;\n page?.frames.delete(frameId);\n },\n clear: () => {\n pages.clear();\n },\n };\n};\n\nexport type PageRegistry = ReturnType<typeof makePageRegistry>;\n\nexport interface PageControlPort {\n readonly state: (\n page: PageInfo,\n options?: OperationOptions,\n ) => Effect.Effect<PageExecutionState, BrowserError>;\n readonly suspend: (\n page: PageInfo,\n options?: OperationOptions,\n ) => Effect.Effect<PageSuspension, BrowserError>;\n readonly resume: (\n receipt: PageSuspension,\n options?: OperationOptions,\n ) => Effect.Effect<void, BrowserError>;\n}\n\nexport interface PageControlAssociation {\n readonly port: PageControlPort;\n readonly page: PageInfo;\n}\n\n/** What one issued Page carries: its record, controls, capture parent and page control. */\nexport interface IssuedPage {\n readonly record: PageRecord;\n readonly controls: PageControls;\n readonly capture: PageCaptureParent;\n readonly pageControl: PageControlAssociation;\n}\n\ntype Issued =\n | { readonly _tag: \"Session\"; readonly capture: CaptureParent }\n | ({ readonly _tag: \"Page\" } & IssuedPage)\n | { readonly _tag: \"Frame\"; readonly owner: Owner; readonly controls: PageControls };\n\n// This is a private capability registry, not stored domain data. Exact live identity is required:\n// spreading or cloning a session, Page or Frame must not copy authority over its owner, capture\n// leases, reservations or page control. A public or enumerable field would weaken that boundary.\n// Schemas describe data, never this mutable ownership state.\nconst issued = new WeakMap<object, Issued>();\n// One canonical Page per page record: issuing the same record again returns the same object.\nconst canonical = new WeakMap<PageRecord, Page>();\n\n/** Registers a session's own capture parent under the session object itself. */\nexport const issueSession = (session: object, capture: CaptureParent): void => {\n issued.set(session, { _tag: \"Session\", capture });\n};\n\n/** The canonical Page for `record`: built by `make` and registered the first time only. */\nexport const issuePage = (\n record: PageRecord,\n make: () => Page,\n authority: () => Omit<IssuedPage, \"record\">,\n): Page => {\n const existing = canonical.get(record);\n\n if (existing !== undefined) return existing;\n const page = make();\n const { controls, capture, pageControl } = authority();\n\n canonical.set(record, page);\n issued.set(page, {\n _tag: \"Page\",\n record,\n controls,\n capture,\n pageControl: { port: pageControl.port, page: Object.freeze({ ...pageControl.page }) },\n });\n\n return page;\n};\n\n/** An issued Frame keeps its own exact controls and the owner of the session that issued it. */\nexport const issueFrame = (frame: object, owner: Owner, controls: PageControls): void => {\n issued.set(frame, { _tag: \"Frame\", owner, controls });\n};\n\nconst sessionOwner = (session: object): Owner | undefined => {\n const entry = issued.get(session);\n\n return entry?._tag === \"Session\" ? entry.capture.owner : undefined;\n};\n\n/** The issued Page `page` is, if this exact object was issued by the session owning `owner`. */\nexport const issuedPageOf = (page: object, owner: Owner): IssuedPage | undefined => {\n const entry = issued.get(page);\n\n return entry?._tag === \"Page\" && entry.capture.owner === owner ? entry : undefined;\n};\n\n/** Capture binds only to original issued Page authority; a session association is insufficient. */\nexport const capturePageParent = (page: object): PageCaptureParent | undefined => {\n const entry = issued.get(page);\n\n return entry?._tag === \"Page\" ? entry.capture : undefined;\n};\n\n/** The page control an issued Page carries. */\nexport const pageControl = (page: object): PageControlAssociation | undefined => {\n const entry = issued.get(page);\n\n return entry?._tag === \"Page\" ? entry.pageControl : undefined;\n};\n\nconst unregistered = (operation: BrowserOperation) =>\n Effect.fail(\n BrowserError.make({\n operation,\n reason: Reasons.UnregisteredSession.make({}),\n outcome: \"undispatched\",\n }),\n );\n\n/** Provider bridges borrow the exact issued page on this session's original owner. */\nexport const resolvePageControlsForSession = (\n session: object,\n page: object,\n operation: BrowserOperation = \"target\",\n): Effect.Effect<PageControls, BrowserError> =>\n Effect.suspend(() => {\n const owner = sessionOwner(session);\n const entry = owner === undefined ? undefined : issuedPageOf(page, owner);\n\n return entry === undefined\n ? unregistered(operation)\n : entry.controls.validate(operation).pipe(Effect.as(entry.controls));\n });\n\n/**\n * Tools borrow an exact issued Page, or an exact Frame one of its Pages issued, on this session's\n * original owner. Capture, page control and provider transfers stay Page-only.\n */\nexport const resolveTargetControlsForSession = (\n session: object,\n target: object,\n operation: BrowserOperation = \"target\",\n): Effect.Effect<PageControls, BrowserError> =>\n Effect.suspend(() => {\n const entry = issued.get(target);\n\n if (entry?._tag !== \"Frame\") return resolvePageControlsForSession(session, target, operation);\n if (sessionOwner(session) !== entry.owner) return unregistered(operation);\n\n return entry.controls.validate(operation).pipe(Effect.as(entry.controls));\n });\n"],"mappings":";;;;;;;AAsDA,MAAa,yBAAyB;CACpC,MAAM,wBAAQ,IAAI,IAAyB;CAE3C,MAAM,wBAAQ,IAAI,QAAiC;CAEnD,MAAM,SAAS,WAAoC;EACjD,MAAM,QAAQ,MAAM,IAAI,MAAM;EAE9B,IAAI,UAAU,KAAA,GAAW,MAAM,IAAI,UAAU,yCAAyC;EAEtF,OAAO;CACT;CAEA,OAAO;EACL,MAAM,WAA2C,MAAM,IAAI,MAAM;EACjE,eAA0C,CAAC,GAAG,MAAM,OAAO,CAAC;;EAE5D,MAAM,SAQY;GAChB,MAAM,SAAsB;IAC1B,UAAU,KAAK;IACf,WAAW,KAAK;IAChB,MAAM,KAAK;IACX,wBAAQ,IAAI,IAAI;IAChB,OAAO,KAAK,SAAS,WAAW;IAChC,aAAa,EAAE,MAAM,cAAc;IACnC,OAAO,KAAK;IACZ,YAAY,KAAK;IACjB,IAAI,WAAW;KACb,OAAO,KAAK,SAAS;IACvB;GACF;GAEA,MAAM,IAAI,QAAQ,MAAM;GACxB,MAAM,IAAI,KAAK,KAAK,QAAQ,MAAM;GAElC,OAAO;EACT;;EAEA,QAAQ,WAAmB;GACzB,MAAM,OAAO,MAAM,IAAI,MAAM;GAE7B,IAAI,SAAS,KAAA,KAAa,KAAK,UAAU,QAAQ,KAAK,QAAQ;EAChE;;EAEA,UAAU,WAAmB;GAC3B,MAAM,OAAO,MAAM,IAAI,MAAM;GAE7B,IAAI,SAAS,KAAA,KAAa,KAAK,UAAU,UAAU,KAAK,QAAQ;EAClE;;EAEA,SAAS,WAAmB;GAC1B,MAAM,OAAO,MAAM,IAAI,MAAM;GAE7B,IAAI,SAAS,KAAA,GAAW;GACxB,KAAK,QAAQ;GACb,IAAI,KAAK,YAAY,KAAA,GAAW,SAAS,WAAW,KAAK,SAAS,OAAO,QAAQ,IAAI,CAAC;GACtF,MAAM,OAAO,MAAM;EACrB;;EAEA,UAAU,QAAoB,gBAA2C;GACvE,MAAM,MAAM,CAAC,CAAC,cAAc;EAC9B;;EAEA,aAAa,QAAoB,YAAwC;GACvE,MAAM,MAAM,CAAC,CAAC,UAAU;EAC1B;;EAEA,QAAQ,QAAoB,YAAiC;GAC3D,MAAM,OAAO,MAAM,MAAM;GACzB,MAAM,WAAW,KAAK,OAAO,IAAI,OAAO;GAExC,IAAI,aAAa,KAAA,GAAW,OAAO;GACnC,MAAM,QAAoB,EAAE,UAAU,MAAM;GAE5C,KAAK,OAAO,IAAI,SAAS,KAAK;GAE9B,OAAO;EACT;;EAEA,cAAc,QAAgB,YAAoB;GAChD,MAAM,OAAO,MAAM,IAAI,MAAM;GAC7B,MAAM,QAAQ,MAAM,OAAO,IAAI,OAAO;GAEtC,IAAI,UAAU,KAAA,GAAW,MAAM,WAAW;GAC1C,MAAM,OAAO,OAAO,OAAO;EAC7B;EACA,aAAa;GACX,MAAM,MAAM;EACd;CACF;AACF;AAyCA,MAAM,yBAAS,IAAI,QAAwB;AAE3C,MAAM,4BAAY,IAAI,QAA0B;;AAGhD,MAAa,gBAAgB,SAAiB,YAAiC;CAC7E,OAAO,IAAI,SAAS;EAAE,MAAM;EAAW;CAAQ,CAAC;AAClD;;AAGA,MAAa,aACX,QACA,MACA,cACS;CACT,MAAM,WAAW,UAAU,IAAI,MAAM;CAErC,IAAI,aAAa,KAAA,GAAW,OAAO;CACnC,MAAM,OAAO,KAAK;CAClB,MAAM,EAAE,UAAU,SAAS,gBAAgB,UAAU;CAErD,UAAU,IAAI,QAAQ,IAAI;CAC1B,OAAO,IAAI,MAAM;EACf,MAAM;EACN;EACA;EACA;EACA,aAAa;GAAE,MAAM,YAAY;GAAM,MAAM,OAAO,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC;EAAE;CACtF,CAAC;CAED,OAAO;AACT;;AAGA,MAAa,cAAc,OAAe,OAAc,aAAiC;CACvF,OAAO,IAAI,OAAO;EAAE,MAAM;EAAS;EAAO;CAAS,CAAC;AACtD;AAEA,MAAM,gBAAgB,YAAuC;CAC3D,MAAM,QAAQ,OAAO,IAAI,OAAO;CAEhC,OAAO,OAAO,SAAS,YAAY,MAAM,QAAQ,QAAQ,KAAA;AAC3D;;AAGA,MAAa,gBAAgB,MAAc,UAAyC;CAClF,MAAM,QAAQ,OAAO,IAAI,IAAI;CAE7B,OAAO,OAAO,SAAS,UAAU,MAAM,QAAQ,UAAU,QAAQ,QAAQ,KAAA;AAC3E;;AAGA,MAAa,qBAAqB,SAAgD;CAChF,MAAM,QAAQ,OAAO,IAAI,IAAI;CAE7B,OAAO,OAAO,SAAS,SAAS,MAAM,UAAU,KAAA;AAClD;;AAGA,MAAa,eAAe,SAAqD;CAC/E,MAAM,QAAQ,OAAO,IAAI,IAAI;CAE7B,OAAO,OAAO,SAAS,SAAS,MAAM,cAAc,KAAA;AACtD;AAEA,MAAM,gBAAgB,cACpB,OAAO,KACL,aAAa,KAAK;CAChB;CACA,QAAQ,QAAQ,oBAAoB,KAAK,CAAC,CAAC;CAC3C,SAAS;AACX,CAAC,CACH;;AAGF,MAAa,iCACX,SACA,MACA,YAA8B,aAE9B,OAAO,cAAc;CACnB,MAAM,QAAQ,aAAa,OAAO;CAClC,MAAM,QAAQ,UAAU,KAAA,IAAY,KAAA,IAAY,aAAa,MAAM,KAAK;CAExE,OAAO,UAAU,KAAA,IACb,aAAa,SAAS,IACtB,MAAM,SAAS,SAAS,SAAS,CAAC,CAAC,KAAK,OAAO,GAAG,MAAM,QAAQ,CAAC;AACvE,CAAC;;;;;AAMH,MAAa,mCACX,SACA,QACA,YAA8B,aAE9B,OAAO,cAAc;CACnB,MAAM,QAAQ,OAAO,IAAI,MAAM;CAE/B,IAAI,OAAO,SAAS,SAAS,OAAO,8BAA8B,SAAS,QAAQ,SAAS;CAC5F,IAAI,aAAa,OAAO,MAAM,MAAM,OAAO,OAAO,aAAa,SAAS;CAExE,OAAO,MAAM,SAAS,SAAS,SAAS,CAAC,CAAC,KAAK,OAAO,GAAG,MAAM,QAAQ,CAAC;AAC1E,CAAC"}
|