@panerelay/browser-registry
Advanced tools
+2
-0
@@ -38,2 +38,4 @@ import { PANERELAY_PROTOCOL_VERSION, type BridgeState } from '@panerelay/protocol'; | ||
| export declare function selectBrowserRegistration(options?: BrowserRegistryOptions): Promise<BrowserSelection>; | ||
| /** Selects a live registration using RFC-0006 routing, but requires browser-fetch support. */ | ||
| export declare function selectBrowserFetchRegistration(options?: BrowserRegistryOptions): Promise<BrowserSelection>; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,0BAA0B,EAG1B,KAAK,WAAW,EAEjB,MAAM,qBAAqB,CAAC;AAG7B,eAAO,MAAM,wBAAwB,EAAG,sBAA+B,CAAC;AACxE,eAAO,MAAM,qBAAqB,EAAG,mBAA4B,CAAC;AAClE,eAAO,MAAM,mCAAmC,EAAG,iCAA0C,CAAC;AAC9F,eAAO,MAAM,kCAAkC,EAAG,gCAAyC,CAAC;AAI5F,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,OAAO,0BAA0B,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrD,KAAK,EAAE,WAAW,CAAC;CACpB;AAMD,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAMrF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAM/E;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,sBAA2B,GACnC,MAAM,CAGR;AAyED,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAGf;AAkBD,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAE7B;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAiCtC;AAED,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,QAAQ,SAAc,EACtB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAOrC;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CAS9B;AAED,wBAAsB,mBAAmB,CACvC,iBAAiB,CAAC,EAAE,MAAM,EAC1B,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA8BrC;AAoBD,wBAAsB,iCAAiC,CACrD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAG7B;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,gBAAgB,CAAC,CAyE3B"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,0BAA0B,EAG1B,KAAK,WAAW,EAEjB,MAAM,qBAAqB,CAAC;AAG7B,eAAO,MAAM,wBAAwB,EAAG,sBAA+B,CAAC;AACxE,eAAO,MAAM,qBAAqB,EAAG,mBAA4B,CAAC;AAClE,eAAO,MAAM,mCAAmC,EAAG,iCAA0C,CAAC;AAC9F,eAAO,MAAM,kCAAkC,EAAG,gCAAyC,CAAC;AAI5F,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,OAAO,0BAA0B,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrD,KAAK,EAAE,WAAW,CAAC;CACpB;AAMD,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAMrF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CAM/E;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,sBAA2B,GACnC,MAAM,CAGR;AA2ED,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAGf;AAkBD,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAE7B;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAiCtC;AAED,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,QAAQ,SAAc,EACtB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAOrC;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CAS9B;AAED,wBAAsB,mBAAmB,CACvC,iBAAiB,CAAC,EAAE,MAAM,EAC1B,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA8BrC;AAoBD,wBAAsB,iCAAiC,CACrD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAG7B;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,gBAAgB,CAAC,CAyE3B;AAWD,8FAA8F;AAC9F,wBAAsB,8BAA8B,CAClD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,gBAAgB,CAAC,CAuE3B"} |
+62
-1
@@ -72,3 +72,5 @@ import { createHash, randomBytes } from 'node:crypto'; | ||
| typeof state.capabilities === 'object' && | ||
| typeof state.capabilities.cdpRelay === 'boolean')) && | ||
| typeof state.capabilities.cdpRelay === 'boolean' && | ||
| (state.capabilities.browserFetch === undefined || | ||
| typeof state.capabilities.browserFetch === 'boolean'))) && | ||
| typeof state.updatedAt === 'string' && | ||
@@ -271,1 +273,60 @@ Number.isFinite(Date.parse(state.updatedAt))); | ||
| } | ||
| function assertFetchReady(state) { | ||
| if (state.capabilities?.browserFetch !== true) { | ||
| throw new Error(`${state.browserName} does not support Panerelay fetch. Update and reload its Panerelay Extension.`); | ||
| } | ||
| return state; | ||
| } | ||
| /** Selects a live registration using RFC-0006 routing, but requires browser-fetch support. */ | ||
| export async function selectBrowserFetchRegistration(options = {}) { | ||
| const currentRegistrations = await listBrowserRegistrations(options); | ||
| const legacy = currentRegistrations.length === 0 ? await readLiveLegacyBrowserRegistration(options) : null; | ||
| const registrations = legacy | ||
| ? [{ state: legacy, ready: legacy.capabilities?.browserFetch === true }] | ||
| : currentRegistrations.map(registration => ({ | ||
| state: registration.state, | ||
| ready: registration.state.capabilities?.browserFetch === true, | ||
| })); | ||
| const ready = registrations.filter(registration => registration.ready); | ||
| const selectedSource = (currentSource) => (legacy ? 'legacy' : currentSource); | ||
| const env = environment(options); | ||
| const exactSelector = env[PANERELAY_BROWSER_ID_ENV]?.trim(); | ||
| const browserSelector = env[PANERELAY_BROWSER_ENV]?.trim(); | ||
| const selector = exactSelector || browserSelector; | ||
| if (selector) { | ||
| const exact = registrations.find(registration => registration.state.browserId === selector); | ||
| if (exact) | ||
| return { source: selectedSource('explicit'), state: assertFetchReady(exact.state) }; | ||
| if (exactSelector) { | ||
| throw new Error(`Panerelay browser ${exactSelector} is unavailable. Reopen that browser or choose another registration.`); | ||
| } | ||
| const normalized = selector.toLowerCase(); | ||
| if (BROWSER_FAMILIES.has(normalized)) { | ||
| const matches = ready.filter(registration => (registration.state.browserFamily ?? 'unknown') === normalized); | ||
| if (matches.length === 1) { | ||
| return { source: selectedSource('explicit'), state: matches[0].state }; | ||
| } | ||
| if (matches.length > 1) { | ||
| throw new Error(`Panerelay browser selector "${selector}" is ambiguous. Use PANERELAY_BROWSER_ID with one of: ${describeRegistrations(matches)}`); | ||
| } | ||
| } | ||
| throw new Error(`Panerelay browser selector "${selector}" cannot provide fetch. Live browsers: ${describeRegistrations(registrations) || 'none'}`); | ||
| } | ||
| const savedDefault = await readBrowserDefault(options); | ||
| if (savedDefault) { | ||
| const selected = registrations.find(registration => registration.state.browserId === savedDefault.browserId); | ||
| if (!selected || !selected.ready) { | ||
| throw new Error(`The default Panerelay browser (${savedDefault.browserId}) cannot provide fetch. Reopen it, update its Extension, choose another default, or clear the default.`); | ||
| } | ||
| return { source: selectedSource('default'), state: selected.state }; | ||
| } | ||
| if (ready.length === 1) | ||
| return { source: selectedSource('single'), state: ready[0].state }; | ||
| if (ready.length > 1) { | ||
| throw new Error(`Multiple Panerelay browsers can provide fetch. Set a default or use PANERELAY_BROWSER_ID with one of: ${describeRegistrations(ready)}`); | ||
| } | ||
| if (registrations.length > 0) { | ||
| throw new Error(`No registered Panerelay browser can provide fetch. Update and reload the Extension. Registered browsers: ${describeRegistrations(registrations)}`); | ||
| } | ||
| throw new Error('Panerelay Bridge is unavailable. Build and load the Extension.'); | ||
| } |
+4
-3
| { | ||
| "name": "@panerelay/browser-registry", | ||
| "version": "0.8.0", | ||
| "version": "0.9.0", | ||
| "description": "Protected local browser registration and deterministic routing for Panerelay.", | ||
@@ -35,3 +35,3 @@ "type": "module", | ||
| "dependencies": { | ||
| "@panerelay/protocol": "0.8.0" | ||
| "@panerelay/protocol": "0.9.0" | ||
| }, | ||
@@ -41,4 +41,5 @@ "scripts": { | ||
| "typecheck": "tsc -p tsconfig.json --noEmit", | ||
| "test": "pnpm run build && node ../../scripts/run-compiled-tests.mjs dist" | ||
| "test": "pnpm run build && pnpm run test:compiled", | ||
| "test:compiled": "node ../../scripts/run-compiled-tests.mjs dist" | ||
| } | ||
| } |
22988
21.4%369
20.59%+ Added
- Removed
Updated