@aperture-browser/session-element 0.0.0-init.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +62 -0
- package/dist/aperture-session-view.js +5 -0
- package/dist/aperture-session.js +11 -0
- package/dist/aperture-t-Xm6-Va.js +22 -0
- package/dist/headless.d.ts +44 -0
- package/dist/index.d.ts +24 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Taras Fomin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# @aperture-browser/session-element
|
|
2
|
+
|
|
3
|
+
Custom elements that embed a live [Aperture](https://github.com/tarik02/aperture) browser session in any page. They render into Shadow DOM, so the page's styles and the session's never mix, and bundle React and everything else they need.
|
|
4
|
+
|
|
5
|
+
- `<aperture-session>`: the session with its UI: tabs, toolbar and menus.
|
|
6
|
+
- `<aperture-session-view>`: the session alone, for pages that build their own controls. It skips the UI kit and stylesheet, so it is much smaller.
|
|
7
|
+
|
|
8
|
+
## `<aperture-session>`
|
|
9
|
+
|
|
10
|
+
```html
|
|
11
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@aperture-browser/session-element/dist/aperture-session.js"></script>
|
|
12
|
+
|
|
13
|
+
<aperture-session
|
|
14
|
+
base-url="https://aperture.example"
|
|
15
|
+
token="apv_…"
|
|
16
|
+
style="display: block; height: 600px"
|
|
17
|
+
></aperture-session>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or from a bundler: `import "@aperture-browser/session-element";`.
|
|
21
|
+
|
|
22
|
+
Attributes:
|
|
23
|
+
|
|
24
|
+
- `token`: a share link's editor (`ape_…`) or viewer (`apv_…`) token; the element grants exactly what the link grants.
|
|
25
|
+
- `base-url`: the Aperture instance, when it is not the page's own origin. The instance must list your origin in `embed_allowed_origins`.
|
|
26
|
+
- `hide`: parts of the UI to leave out, separated by spaces: `tabs`, `navigation` (back, forward, reload), `address-bar`, `presence`, `drawing`, `menus`, `status-badge`, `toaster`.
|
|
27
|
+
|
|
28
|
+
The `features` property takes the same switches as the React component's `features` prop, e.g. `element.features = { tabs: false, addressBar: false }`. It is applied on top of `hide`.
|
|
29
|
+
- `theme`: `light`, `dark` or `system` (the default).
|
|
30
|
+
|
|
31
|
+
The element fills the size you give it. It uses the page's font; set `--aperture-font-sans` and `--aperture-font-mono` (used for URLs) on the element to pick others. It adds one `<style>` to the page for its CSS custom property registrations, which browsers ignore inside shadow roots.
|
|
32
|
+
|
|
33
|
+
## `<aperture-session-view>`
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@aperture-browser/session-element/dist/aperture-session-view.js"></script>
|
|
37
|
+
|
|
38
|
+
<aperture-session-view id="session" base-url="https://aperture.example" token="ape_…"></aperture-session-view>
|
|
39
|
+
|
|
40
|
+
<script type="module">
|
|
41
|
+
const session = document.getElementById("session");
|
|
42
|
+
session.addEventListener("aperture-change", ({ detail }) => {
|
|
43
|
+
console.log(detail.status, detail.tabs, detail.activeTabId);
|
|
44
|
+
});
|
|
45
|
+
await session.whenConnected();
|
|
46
|
+
await session.navigate("https://example.com");
|
|
47
|
+
</script>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Or from a bundler: `import "@aperture-browser/session-element/headless";`.
|
|
51
|
+
|
|
52
|
+
It takes the `token` and `base-url` attributes and shows the active tab, forwarding input to it.
|
|
53
|
+
|
|
54
|
+
- `snapshot` holds the current state: `status` (`loading`, `ready`, `invalid`, `expired` or `unavailable`), `role`, `connection`, `tabs` (`id`, `title`, `url`, `loading`) and `activeTabId`. The `aperture-change` event carries each new snapshot.
|
|
55
|
+
- Methods: `navigate(url)`, `back()`, `forward()`, `reload()`, `stop()`, `openTab(url?)`, `closeTab(id)`, `activateTab(id)`. They act on the active tab where it applies and return a promise that resolves once Aperture has carried the command out; `openTab` resolves with the new tab's id. The promise rejects with an `Error` (`_tag` `LiveSessionError`) whose `message` says why: the session is not connected yet, or Aperture refused the command, for example a viewer token trying to navigate.
|
|
56
|
+
- `whenConnected()` resolves with the snapshot once the session is connected, and rejects if the token turns out invalid, expired or unavailable.
|
|
57
|
+
- `reconnect()` drops the connection and opens it again.
|
|
58
|
+
- The `aperture-notice` event carries errors and confirmations (`level`, `message`) that `<aperture-session>` would show as toasts.
|
|
59
|
+
|
|
60
|
+
Both elements load a shared module next to them, so a page that uses both loads React and the session core once.
|
|
61
|
+
|
|
62
|
+
React apps that want to share their own React copy can use [`@aperture-browser/session-react`](https://www.npmjs.com/package/@aperture-browser/session-react) instead, which has the same full and headless split.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{C as e,D as t,T as n,g as r,n as i,o as a,r as o,s,t as c}from"./aperture-t-Xm6-Va.js";var l=t(n(),1),u=e(),d=a(),f={status:`loading`,role:null,connection:`idle`,tabs:[],activeTabId:null},p=`
|
|
2
|
+
:host { display: block; position: relative; overflow: hidden; }
|
|
3
|
+
:host([hidden]) { display: none; }
|
|
4
|
+
.mount { display: flex; height: 100%; }
|
|
5
|
+
`;function m({token:e,onControl:t,onSnapshot:n,onNotice:r}){let{status:i,share:a,control:s}=c({token:e,onNotice:r}),u=(0,l.useMemo)(()=>({status:i,role:a?.role??null,connection:s.phase,tabs:s.targets.map(({id:e,title:t,url:n,loading:r})=>({id:e,title:t,url:n,loading:r})),activeTabId:s.activeTargetId}),[s.activeTargetId,s.phase,s.targets,a,i]);return(0,l.useEffect)(()=>t(s)),(0,l.useEffect)(()=>n(u),[n,u]),i===`ready`?(0,d.jsx)(o,{control:s}):null}var h=class extends HTMLElement{static observedAttributes=[`token`,`base-url`];#e=null;#t=null;#n=f;get snapshot(){return this.#n}navigate(e){return this.#i(t=>t.navigate(e))}back(){return this.#i(e=>e.historyBack())}forward(){return this.#i(e=>e.historyForward())}reload(){return this.#i(e=>e.reload())}stop(){return this.#i(e=>e.stopLoading())}openTab(e){return this.#i(t=>t.createTarget(e))}closeTab(e){return this.#i(t=>t.closeTarget(e))}activateTab(e){return this.#i(t=>t.activateTarget(e)).then(async()=>{await this.#r(t=>t.activeTabId===e)})}reconnect(){this.#t?.reconnect()}whenConnected(){return this.#r(e=>e.connection===`connected`)}#r(e){return new Promise((t,n)=>{let r=()=>{let i=this.#n;if(e(i))t(i);else if(i.status===`invalid`||i.status===`expired`||i.status===`unavailable`)n(new s({message:`the session is ${i.status}`}));else return;this.removeEventListener(`aperture-change`,r)};this.addEventListener(`aperture-change`,r),r()})}#i(e){let t=this.#t;return t?r(e(t.commands)):Promise.reject(new s({message:`the session is not connected`}))}connectedCallback(){let e=this.shadowRoot??this.attachShadow({mode:`open`});e.replaceChildren();let t=document.createElement(`style`);t.textContent=p;let n=document.createElement(`div`);n.className=`mount`,e.append(t,n),this.#e=(0,u.createRoot)(n),this.#c()}disconnectedCallback(){this.#e?.unmount(),this.#e=null,this.#t=null}attributeChangedCallback(){this.#c()}#a=e=>{this.#t=e};#o=e=>{JSON.stringify(e)!==JSON.stringify(this.#n)&&(this.#n=e,this.dispatchEvent(new CustomEvent(`aperture-change`,{detail:e})))};#s=e=>{this.dispatchEvent(new CustomEvent(`aperture-notice`,{detail:e}))};#c(){let e=this.getAttribute(`token`),t=this.getAttribute(`base-url`)??void 0;this.#e?.render(e?(0,d.jsx)(i,{baseUrl:t,children:(0,d.jsx)(m,{token:e,onControl:this.#a,onSnapshot:this.#o,onNotice:this.#s})},t??``):null)}};customElements.get(`aperture-session-view`)||customElements.define(`aperture-session-view`,h);export{h as ApertureSessionViewElement};
|