import { P as Platform, a as BeacioOptions, b as BeacioBackgroundSync, c as BeacioPeripheral, R as RequestDeviceOptions, d as BeacioDevice } from './base-BkianuQ_.js'; export { A as ActiveSubscription, e as AutoReconnectOptions, f as BackgroundConnectionOptions, g as BackgroundRegistration, h as BackgroundRegistrationType, B as BaseProfile, i as BeacioError, j as BeacioPeripheralAdvertisingOptions, k as BeacioPeripheralCharacteristicDefinition, l as BeacioPeripheralCharacteristicProperty, m as BeacioPeripheralCharacteristicRecord, n as BeacioPeripheralConnectionStateChange, o as BeacioPeripheralEventMap, p as BeacioPeripheralNotificationReady, q as BeacioPeripheralSendOptions, r as BeacioPeripheralSendResult, s as BeacioPeripheralServiceDefinition, t as BeacioPeripheralServiceRecord, u as BeacioPeripheralSubscriptionChange, v as BeacioPeripheralWriteRequest, w as BeaconScanFilter, x as BeaconScanningOptions, y as BluetoothLEScanFilter, C as CharacteristicNotificationOptions, z as ConditionDecoder, D as ConditionOperator, E as ConnectOptions, F as DEFAULT_BEACIO_OPTIONS, G as DEFAULT_RETRY_OPTIONS, H as DeviceErrorContext, I as DisconnectReason, N as NativeOverflowEvent, J as NotificationCallback, K as NotificationCondition, L as NotificationOptions, M as NotificationOverflowStrategy, O as NotificationPermissionState, Q as NotificationTemplate, S as QueueOverflowEvent, T as ReadOptions, U as ReplyActionConfig, V as RetryOptions, W as SubscribeOptions, X as SubscriptionLostEvent, Y as WriteAutoOptions, Z as WriteAutoResult, _ as WriteFragmentedOptions, $ as WriteFragmentedResult, a0 as WriteLargeOptions, a1 as WriteLargeResult, a2 as WriteLimits, a3 as WriteMode, a4 as WriteOptions, a5 as defineProfile, a6 as parseRawBytes, a7 as withRetry } from './base-BkianuQ_.js'; export { P as Percentage, c as clampPercent, p as percent } from './units-C2kcsu3V.js'; export { BLE_UUIDS, MockAdvertisementOptions, MockBleDevice, MockBluetooth, MockBluetoothOptions, MockCharacteristic, MockCharacteristicConfig, MockDescriptor, MockDescriptorConfig, MockDeviceOptions, MockGATTServer, MockService, MockServiceConfig, createMockBluetooth, installMockBluetooth, devices as mockDevices } from './testing/index.js'; export { OptionalServicesSource, ProfileWithServices, deriveOptionalServices } from './profiles/index.js'; export { HEART_RATE_SERVICES, HeartRateData, HeartRateProfile, parseHeartRate } from './profiles/heart-rate.js'; export { BatteryProfile } from './profiles/battery.js'; export { DeviceInfo, DeviceInfoProfile } from './profiles/device-info.js'; export { NUS_SERVICES, NordicUARTProfile } from './profiles/nordic-uart.js'; export { HM10SerialProfile } from './profiles/serial-ffe0.js'; export { B as BeacioErrorCode } from './error-taxonomy-CWrJx3aZ.js'; /** * Core Beacio SDK entry point. Handles platform detection and device discovery. * * @example * ```typescript * import { Beacio } from '@beacio/core' * * const ble = new Beacio() * const device = await ble.requestDevice({ * filters: [{ services: ['heart_rate'] }] * }) * await device.connect() * ``` */ declare class Beacio { readonly platform: Platform; readonly isSupported: boolean; readonly maxConnections: number | null; private bluetooth; private readonly runtimeBluetooth; private readonly unsupportedFeatureErrorFactory; private readonly unsupportedBackgroundSync; private readonly unsupportedPeripheral; private readonly devices; /** * Instance-wide optionalServices registry. Holds canonical 128-bit UUIDs * (already {@link resolveUUID}-normalized); a Set both de-dups and preserves * registration order. {@link requestDevice} unions this into the effective * `optionalServices` of every call. Seeded from {@link BeacioOptions.defaultOptionalServices}. */ private readonly registeredOptionalServices; constructor(options?: BeacioOptions); /** * Access the background sync API for maintaining BLE connections and delivering * iOS notifications when Safari is not in the foreground. * * Requires the companion app running in IPC relay mode. Returns a stub that * throws `BLUETOOTH_UNAVAILABLE` when Bluetooth is unavailable, or * `GATT_OPERATION_FAILED` when the extension runtime is missing. * * @see {@link BeacioBackgroundSync} */ get backgroundSync(): BeacioBackgroundSync; /** * Access the peripheral-mode API for acting as a BLE GATT server. * * Allows registering services, advertising, and sending notifications to * connected centrals. Returns a stub that throws `GATT_OPERATION_FAILED` * on unsupported platforms. * * @see {@link BeacioPeripheral} */ get peripheral(): BeacioPeripheral; /** * Prompt the user to select a BLE device. Open the browser's device picker * filtered by the given options. * * **Filter semantics:** * - `filters` array entries are OR-combined -- a device matches if ANY filter matches * - Within a single filter, all specified fields are AND-combined -- device must match ALL * - `exclusionFilters` are applied after `filters` to remove unwanted matches * - `acceptAllDevices: true` cannot be combined with `filters` * * **Service access:** Only services declared in `filters[].services` or `optionalServices` * can be accessed after connection. `optionalServices` does NOT affect the picker -- it * only declares post-connection GATT access intent. * * Service names (e.g. `'heart_rate'`) are resolved to full 128-bit UUIDs via {@link resolveUUID}. * * @param options - Device filter and service access options. Defaults to `{ acceptAllDevices: true }`. * @returns A {@link BeacioDevice} wrapping the user-selected device. * * @throws {BeacioError} `BLUETOOTH_UNAVAILABLE` -- browser or platform does not support Web Bluetooth * @throws {BeacioError} `USER_CANCELLED` -- user dismissed the device picker without selecting * @throws {BeacioError} `DEVICE_NOT_FOUND` -- no devices matched the given filters * @throws {BeacioError} `PERMISSION_DENIED` -- request was not triggered by a user gesture * * @example * ```typescript * // OR filter: match devices with heart_rate OR battery_service * const device = await ble.requestDevice({ * filters: [ * { services: ['heart_rate'] }, * { services: ['battery_service'] }, * ], * }) * * // AND within filter: must have heart_rate AND name starting with "Polar" * const device = await ble.requestDevice({ * filters: [{ services: ['heart_rate'], namePrefix: 'Polar' }], * optionalServices: ['battery_service'], * }) * * // Accept all devices (no filtering) * const device = await ble.requestDevice({ acceptAllDevices: true }) * ``` * * @see {@link RequestDeviceOptions} * @see {@link resolveUUID} */ requestDevice(options?: RequestDeviceOptions): Promise; /** * Register service UUIDs once for this instance so they are merged into the * effective `optionalServices` of every subsequent {@link requestDevice} call — * eliminating the per-call `optionalServices` boilerplate when a site or agent * always needs the same allowlist (e.g. a vendor's full multi-family service * bundle). Pairs with {@link BeacioOptions.defaultOptionalServices}. * * Accumulating and idempotent: each UUID is resolved via {@link resolveUUID} * (names, 4/8-hex, or full 128-bit all accepted) to its canonical lowercase * 128-bit form and stored in a de-duped, insertion-ordered set, so registering * the same service twice — by alias or canonical form — is a no-op. * * **Picker-safe:** this declares post-connection GATT access intent ONLY. It * never widens the device picker — it does not add to `filters`, does not * synthesize `acceptAllDevices`, and the registered set is unioned into * `optionalServices` (caller entries first), never a replacement. * * @param uuids - Service names, 4/8-hex, or full 128-bit UUID strings to register. * @throws {TypeError} If a value is not a resolvable UUID or known SIG name (via {@link resolveUUID}). * * @example * ```typescript * import { Beacio } from '@beacio/core' * import { StorzBickel } from '@beacio/core/experimental/profiles/storz-bickel' * * const ble = new Beacio() * ble.registerServices(StorzBickel.allServices()) // declare every S&B family once * // ...every requestDevice() now carries the bundle as optionalServices. * ``` * * @see {@link requestDevice} * @see {@link BeacioOptions.defaultOptionalServices} */ registerServices(uuids: string[]): void; /** * Return previously granted devices without prompting the user. * Only available on platforms that implement `Bluetooth.getDevices()` (e.g. Chrome). * Returns an empty array when unsupported. * * @returns Array of previously paired {@link BeacioDevice} instances, or empty if unsupported. * @throws {BeacioError} `BLUETOOTH_UNAVAILABLE` -- no Bluetooth API available */ getDevices(): Promise; /** * Check if Bluetooth is available on this device/browser. * Returns `false` gracefully when the API is missing or throws. * * @returns `true` if Bluetooth is available and can be used for device discovery. */ getAvailability(): Promise; /** * Start a BLE advertisement scan. Returns `null` when the platform does not support * `Bluetooth.requestLEScan()`. * * @param options - Scan filter options. Defaults to accepting all advertisements. * @returns A `BluetoothLEScan` handle to stop the scan, or `null` if unsupported. * @throws {BeacioError} `BLUETOOTH_UNAVAILABLE` -- no Bluetooth API available */ requestLEScan(options?: BluetoothLEScanOptions): Promise; private normalizeRequestDeviceOptions; /** * Compute the effective `optionalServices` for a request: the de-duped UNION * of the caller-supplied list (resolved + first, preserving caller order) and * the instance registry (already canonical). Returns `undefined` when both are * empty, so the caller can omit the key and keep an empty registry a no-op. * This NEVER touches filters or the picker — it only assembles the access list. */ private mergeOptionalServices; private normalizeMaxConnections; private wrapDevice; private assertConnectionCapacity; } declare const chunkSizeBrand: unique symbol; /** * A validated, strictly-positive integer chunk size in bytes. * * Nominal/branded: the brand can only be attached by {@link chunkSize} or * {@link clampChunkSize}, both of which guarantee `value >= 1`. Typing a chunk * loop's stride as `ChunkSize` makes a `0` (or negative) increment * unrepresentable at `offset += step`, eliminating the zero-stride infinite * loop at the type level — not just by runtime check. */ type ChunkSize = number & { readonly [chunkSizeBrand]: true; }; /** * Strict smart-constructor for {@link ChunkSize}. Throws `INVALID_PARAMETER` * on a non-integer or non-positive value. Use when the caller supplied an * explicit size that must be rejected (not silently corrected) if invalid. */ declare function chunkSize(n: number): ChunkSize; /** * Lenient smart-constructor for {@link ChunkSize}. Coerces any * `null`/`undefined`/`0`/negative/`NaN`/non-integer input to a positive * `fallback` (default {@link DEFAULT_CHUNK_SIZE}). Never returns `<= 0`. * * This is the single clamp for platform-reported limits, where a literal `0` * (a valid `number | null` per {@link WriteLimits}) must be treated as "no * usable limit" rather than a zero-length stride. */ declare function clampChunkSize(n: number | null | undefined, fallback?: number): ChunkSize; /** * `BluetoothUUID.canonicalUUID(alias)` (§7): expand a 16/32-bit alias into the * canonical lowercase 128-bit UUID string. Applies the WebIDL `[EnforceRange] * unsigned long` conversion: ToNumber, reject non-finite, truncate toward zero, * reject outside [0, 2^32 − 1]. Fractional/numeric-string inputs CONVERT. */ declare function canonicalUUID(alias: number): string; /** * Resolve a service/characteristic name, number, or short UUID to a full 128-bit UUID string. * * **Supported input formats:** * 1. **Named alias** -- Bluetooth SIG service or characteristic name (e.g. `'heart_rate'`, `'battery_level'`) * 2. **16-bit integer** -- Numeric service/characteristic ID (e.g. `0x180D`) * 3. **4-hex string** -- Short 16-bit hex (e.g. `'180d'`) * 4. **8-hex string** -- 32-bit hex (e.g. `'0000180d'`) * 5. **Full 128-bit UUID** -- Passed through unchanged (e.g. `'0000180d-0000-1000-8000-00805f9b34fb'`) * * **Fuzzy matching:** If the input looks like a name but does not match any known alias, * Levenshtein edit distance (threshold <= 3) is used to suggest corrections. Name * normalization converts camelCase/PascalCase to snake_case and replaces hyphens/dots/spaces * with underscores before matching. * * @param nameOrUUID - Service/characteristic name, hex string, numeric ID, or full UUID. * @returns Canonical lowercase 128-bit UUID string. * * @throws {TypeError} If a numeric input is out of the 32-bit unsigned range. * @throws {TypeError} If a string input is not a valid UUID format or known name (includes "Did you mean?" hint). * * @example * ```typescript * resolveUUID('heart_rate') // '0000180d-0000-1000-8000-00805f9b34fb' * resolveUUID('180d') // '0000180d-0000-1000-8000-00805f9b34fb' * resolveUUID(0x180D) // '0000180d-0000-1000-8000-00805f9b34fb' * resolveUUID('battery_level') // '00002a19-0000-1000-8000-00805f9b34fb' * resolveUUID('HeartRate') // '0000180d-...' (camelCase normalized) * resolveUUID('heart_rat') // throws Error: Did you mean "heart_rate"? * ``` * * @see {@link getServiceName} for reverse lookup (UUID to name) * @see {@link getCharacteristicName} for reverse lookup (UUID to name) */ declare function resolveUUID(nameOrUUID: string | number): string; /** * Get the human-readable Bluetooth SIG service name for a UUID, if known. * * @param uuid - Full 128-bit UUID string (case-insensitive). * @returns Service name (e.g. `'heart_rate'`), or `undefined` if not a known SIG service. * * @see {@link resolveUUID} for the reverse operation (name to UUID) */ declare function getServiceName(uuid: string): string | undefined; /** * Get the human-readable Bluetooth SIG characteristic name for a UUID, if known. * * @param uuid - Full 128-bit UUID string (case-insensitive). * @returns Characteristic name (e.g. `'heart_rate_measurement'`), or `undefined` if not a known SIG characteristic. * * @see {@link resolveUUID} for the reverse operation (name to UUID) */ declare function getCharacteristicName(uuid: string): string | undefined; /** * Format a Bluetooth SIG snake_case name (e.g. `'heart_rate'`) as Title Case * (e.g. `'Heart Rate'`) for display in a UI. * * Unknown inputs — anything that does not look like a snake_case SIG name, such * as a raw UUID string or hex shorthand — are returned unchanged so callers can * use the raw value as a fallback label. * * @param name - A snake_case SIG name, or a raw UUID/hex string. * @returns Title-cased name, or the input unchanged when it is not a SIG name. * * @example * ```typescript * getDisplayName('heart_rate') // 'Heart Rate' * getDisplayName('heart_rate_measurement') // 'Heart Rate Measurement' * getDisplayName('gap.device_name') // 'Device Name' * getDisplayName('0000180d-0000-1000-8000-00805f9b34fb') // (unchanged) * ``` */ declare function getDisplayName(name: string): string; /** * Resolve a descriptor name or UUID alias to a canonical 128-bit UUID. * Implements `BluetoothUUID.getDescriptor()` from the Web Bluetooth spec * (§7.1 ResolveUUIDName against GATT assigned descriptors only): accepts a * registry descriptor name in its registry dot form * (e.g. `'gatt.client_characteristic_configuration'`), an integer alias, or * a valid lowercase 128-bit UUID. Anything else throws a TypeError. * * @param name - Descriptor name, 16/32-bit integer alias, or full UUID string. * @returns Canonical 128-bit UUID string. * @throws {TypeError} For unknown names, bare hex shorthand, or uppercase UUIDs. * * @example * ```typescript * getDescriptor('gatt.client_characteristic_configuration') // '00002902-...' * getDescriptor(0x2902) // '00002902-...' * ``` * * @see {@link resolveUUID} for the lenient SDK-level resolver */ declare function getDescriptor(name: string | number): string; /** * BluetoothUUID namespace object conforming to the Web Bluetooth spec. * Can be assigned to `window.BluetoothUUID` for spec compliance. * Each getter is scoped to its own GATT assigned-numbers table (§7.1). */ declare const BluetoothUUID: { readonly canonicalUUID: typeof canonicalUUID; readonly getService: (name: string | number) => string; readonly getCharacteristic: (name: string | number) => string; readonly getDescriptor: typeof getDescriptor; }; declare function detectPlatform(): Platform; /** * Get the `Bluetooth` API object for the current platform. * * Returns `navigator.beacio` for the Safari extension, `navigator.bluetooth` for * native Web Bluetooth, or `null` if unsupported. CDN stubs (from `@beacio/detect`) * are excluded. * * @returns The platform's `Bluetooth` API object, or `null` if unavailable. * * @see {@link detectPlatform} for identifying the platform without getting the API */ declare function getBluetoothAPI(): Bluetooth | null; /** * Canonical first-party URLs for the beacio platform. * * Single source of truth so independent packages (detect's install banner, the * react-sdk InstallationWizard) cannot re-diverge onto stale hosts/paths. Lives * in @beacio/core because both @beacio/detect and @beacio/react depend on core * (core depends on nothing) — importing from here introduces no dependency cycle. */ /** * The guided zero-config onboarding page: install → enable the Safari extension * → return. The default destination when no operator-supplied onboarding/App * Store URL override is provided. Authoritative host + path per * outreach/campaign/11-rebrand-manifest.md. */ declare const SETUP_URL = "https://beacio.com/setup"; /** * Canonical beacio CustomEvent names — the single source of truth shared by the * detect dispatcher (@beacio/detect), the react-sdk listeners (@beacio/react), * the extension in-page handshake, and the CDN bundle. * * Lives in @beacio/core for the same reason as `urls.ts`: core depends on * nothing, while @beacio/detect (the dispatcher) and @beacio/react (a listener) * both peer-depend on core — so importing the event-name constants FROM core * introduces no dependency cycle. Both the dispatch side and every listen side * reference these literals, so a diverged or typo'd event name becomes a * compile error rather than a silent half-rebrand break (a listener registered * on a name nobody dispatches). * * `as const` pins each value to its string-literal type (not widened to * `string`); dispatch/listen sites typed against {@link BeacioEventName} reject * any non-member string at compile time. */ declare const BEACIO_EVENTS: { /** Fired on every initBeacio() run with the resolved install state. */ readonly STATE_CHANGE: "beacio:statechange"; /** Fired when the extension is detected and active/ready. */ readonly READY: "beacio:ready"; /** Fired when the extension is installed but Safari still needs activation. */ readonly INSTALLED_INACTIVE: "beacio:installedinactive"; /** Fired when the extension is not installed. */ readonly NOT_INSTALLED: "beacio:notinstalled"; /** The extension's injected script announces it is live and active. */ readonly EXTENSION_READY: "beacio:extension:ready"; /** Page → extension liveness probe. */ readonly EXTENSION_PING: "beacio:extension:ping"; /** Extension → page liveness response. */ readonly EXTENSION_PONG: "beacio:extension:pong"; /** Page → extension request to activate the API. */ readonly EXTENSION_ACTIVATE_REQUEST: "beacio:extension:activate-request"; /** Extension → page result of an activate request. */ readonly EXTENSION_ACTIVATE_RESULT: "beacio:extension:activate-result"; /** Extension announces it is installed (present, not yet active). */ readonly EXTENSION_INSTALLED: "beacio:extension:installed"; /** Extension → page: the injected script's __beacio status transitioned. */ readonly EXTENSION_STATUS_CHANGE: "beacio:extension:statuschange"; }; /** * The union of every canonical beacio CustomEvent name. A value typed as this * cannot be any string other than a {@link BEACIO_EVENTS} member, so a typo at a * dispatch or listen site fails to compile. */ type BeacioEventName = (typeof BEACIO_EVENTS)[keyof typeof BEACIO_EVENTS]; /** * Read an unsigned 8-bit integer from the DataView. * * @param dv - Source DataView from a characteristic read or notification. * @param offset - Byte offset to read from. Defaults to 0. * @returns Unsigned integer in range [0, 255]. * @throws {BeacioError} INVALID_PARAMETER if the DataView is too short for the read. */ declare function readUint8(dv: DataView, offset?: number): number; /** * Read an unsigned 16-bit little-endian integer from the DataView. * Little-endian is the standard byte order for most BLE characteristics. * * @param dv - Source DataView. * @param offset - Byte offset to read from. Defaults to 0. * @returns Unsigned integer in range [0, 65535]. * @throws {BeacioError} INVALID_PARAMETER if the DataView is too short for the read. */ declare function readUint16LE(dv: DataView, offset?: number): number; /** * Read an unsigned 16-bit big-endian integer from the DataView. * * @param dv - Source DataView. * @param offset - Byte offset to read from. Defaults to 0. * @returns Unsigned integer in range [0, 65535]. * @throws {BeacioError} INVALID_PARAMETER if the DataView is too short for the read. */ declare function readUint16BE(dv: DataView, offset?: number): number; /** * Read a signed 16-bit little-endian integer from the DataView. * Common for temperature and other signed sensor values in BLE. * * @param dv - Source DataView. * @param offset - Byte offset to read from. Defaults to 0. * @returns Signed integer in range [-32768, 32767]. * @throws {BeacioError} INVALID_PARAMETER if the DataView is too short for the read. */ declare function readInt16LE(dv: DataView, offset?: number): number; /** * Read an unsigned 32-bit little-endian integer from the DataView. * * @param dv - Source DataView. * @param offset - Byte offset to read from. Defaults to 0. * @returns Unsigned integer in range [0, 4294967295]. * @throws {BeacioError} INVALID_PARAMETER if the DataView is too short for the read. */ declare function readUint32LE(dv: DataView, offset?: number): number; /** * Read a 32-bit little-endian IEEE 754 float from the DataView. * * @param dv - Source DataView. * @param offset - Byte offset to read from. Defaults to 0. * @returns 32-bit floating point number. * @throws {BeacioError} INVALID_PARAMETER if the DataView is too short for the read. */ declare function readFloat32LE(dv: DataView, offset?: number): number; /** * Decode the entire DataView contents as a UTF-8 string. * Useful for device name, serial number, and other string characteristics. * * @param dv - Source DataView. * @returns Decoded UTF-8 string. * * @example * ```typescript * const name = await device.read('generic_access', 'gap.device_name') * console.log(readUtf8(name)) // "Polar H10" * ``` */ declare function readUtf8(dv: DataView): string; /** * Copy the DataView contents into a new `Uint8Array`. * Useful when you need to store, compare, or forward raw bytes. * * @param dv - Source DataView. * @returns New Uint8Array containing a copy of the DataView bytes. */ declare function readBytes(dv: DataView): Uint8Array; export { BEACIO_EVENTS, Beacio, BeacioBackgroundSync, BeacioDevice, type BeacioEventName, BeacioOptions, BeacioPeripheral, BluetoothUUID, type ChunkSize, Platform, RequestDeviceOptions, SETUP_URL, canonicalUUID, chunkSize, clampChunkSize, detectPlatform, getBluetoothAPI, getCharacteristicName, getDescriptor, getDisplayName, getServiceName, readBytes, readFloat32LE, readInt16LE, readUint16BE, readUint16LE, readUint32LE, readUint8, readUtf8, resolveUUID };