{"_id":"@donugr/dgradmobbridge","_rev":"3-6a53fb37c9645b635265b3231c4bd4e7","name":"@donugr/dgradmobbridge","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.1":{"name":"@donugr/dgradmobbridge","version":"0.1.1","keywords":["capacitor","capacitor-plugin","plugin","admob","ads","native-ads","ump","consent","google-ump","gdpr"],"author":{"name":"donugr"},"license":"MIT","_id":"@donugr/dgradmobbridge@0.1.1","maintainers":[{"name":"donugr","email":"donugr@gmail.com"}],"homepage":"https://github.com/donugr/dgradmobbridge#readme","bugs":{"url":"https://github.com/donugr/dgradmobbridge/issues"},"dist":{"shasum":"d4e9f6b90c55a7472d81ffdc42f1946e31bd4c35","tarball":"https://registry.npmjs.org/@donugr/dgradmobbridge/-/dgradmobbridge-0.1.1.tgz","fileCount":27,"integrity":"sha512-535KUfNSHfsrkBnsZCwqO/Zy7ARZsrnTVDHG53k5rh/mNNiTe32Wbq5W6YHg9z+3di3U/Ccp44pphs0ITuLIYA==","signatures":[{"sig":"MEYCIQCqUHgzlmuGEEG34A6R+0ZUl7YsmPr49ULA77jsDkKLgAIhAO2yyo7jw2iaIeXd3eRBnA6MaaO/J02D1Fw9id+iv7p9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":108128},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"d5ccb683c9a2ec2caf8ffcfa75246ea7fdd958b5","scripts":{"build":"npx tsc -p tsconfig.json","clean":"node -e \"import('node:fs').then(fs=>fs.rmSync('dist',{recursive:true,force:true}))\"","prepare":"npm run clean && npm run build","verify:pack":"npm pack --dry-run","release:check":"npm run build && npm run verify:pack"},"_npmUser":{"name":"donugr","email":"donugr@gmail.com"},"capacitor":{"ios":{"src":"ios"},"android":{"src":"android"}},"repository":{"url":"git+https://github.com/donugr/dgradmobbridge.git","type":"git"},"_npmVersion":"10.9.8","description":"Framework-agnostic Capacitor ads facade with standard ads pass-through and a native ads bridge built on top of @capacitor-community/admob.","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.2","@capacitor/core":"^8.0.0"},"peerDependencies":{"@capacitor/core":"^8.0.0","@capacitor-community/admob":"^8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dgradmobbridge_0.1.1_1783051896689_0.3156481756078977","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@donugr/dgradmobbridge","version":"0.1.2","keywords":["capacitor","capacitor-plugin","plugin","admob","ads","native-ads","ump","consent","google-ump","gdpr"],"author":{"name":"donugr"},"license":"MIT","_id":"@donugr/dgradmobbridge@0.1.2","maintainers":[{"name":"donugr","email":"donugr@gmail.com"}],"homepage":"https://github.com/donugr/dgradmobbridge#readme","bugs":{"url":"https://github.com/donugr/dgradmobbridge/issues"},"dist":{"shasum":"c2ce202a14d1d8d12e4862cb504de6e1ec65dd38","tarball":"https://registry.npmjs.org/@donugr/dgradmobbridge/-/dgradmobbridge-0.1.2.tgz","fileCount":27,"integrity":"sha512-AFwfHSVth5ZpBXqHD0+goodpqSZdopuVBO8X2ChHCWpOfCfej6BQ25AIIrCcRuFcM8zsBi2G9Va4XY5ASgmKeg==","signatures":[{"sig":"MEYCIQCtRmvSNEiILZBy42a7/P1m+E5bb1QC+giYRh54yuPshAIhAPdJ4Nbb8GbIgNBAzFZXOeAlILFQu+NvlwBgZuM4OhMh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":109551},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"b81d11805b24eb8854010fd6dd4d2927a762be14","scripts":{"build":"npx tsc -p tsconfig.json","clean":"node -e \"import('node:fs').then(fs=>fs.rmSync('dist',{recursive:true,force:true}))\"","prepare":"npm run clean && npm run build","verify:pack":"npm pack --dry-run","release:check":"npm run build && npm run verify:pack"},"_npmUser":{"name":"donugr","email":"donugr@gmail.com"},"capacitor":{"ios":{"src":"ios"},"android":{"src":"android"}},"repository":{"url":"git+https://github.com/donugr/dgradmobbridge.git","type":"git"},"_npmVersion":"10.9.8","description":"Framework-agnostic Capacitor ads facade with standard ads pass-through and a native ads bridge built on top of @capacitor-community/admob.","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.2","@capacitor/core":"^8.0.0"},"peerDependencies":{"@capacitor/core":"^8.0.0","@capacitor-community/admob":"^8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dgradmobbridge_0.1.2_1783058280471_0.41775448366693824","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@donugr/dgradmobbridge","version":"0.1.3","description":"Framework-agnostic Capacitor ads facade with standard ads pass-through and a native ads bridge built on top of @capacitor-community/admob.","type":"module","sideEffects":false,"main":"dist/index.js","module":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"homepage":"https://github.com/donugr/dgradmobbridge#readme","repository":{"type":"git","url":"git+https://github.com/donugr/dgradmobbridge.git"},"bugs":{"url":"https://github.com/donugr/dgradmobbridge/issues"},"author":{"name":"donugr"},"license":"MIT","keywords":["capacitor","capacitor-plugin","plugin","admob","ads","native-ads","ump","consent","google-ump","gdpr"],"publishConfig":{"access":"public"},"engines":{"node":">=18"},"peerDependencies":{"@capacitor-community/admob":"^8.0.0","@capacitor/core":"^8.0.0"},"devDependencies":{"@capacitor/core":"^8.0.0","typescript":"^5.9.2"},"scripts":{"build":"npx tsc -p tsconfig.json","clean":"node -e \"import('node:fs').then(fs=>fs.rmSync('dist',{recursive:true,force:true}))\"","prepare":"npm run clean && npm run build","verify:pack":"npm pack --dry-run","release:check":"npm run build && npm run verify:pack"},"capacitor":{"ios":{"src":"ios"},"android":{"src":"android"}},"_id":"@donugr/dgradmobbridge@0.1.3","gitHead":"f1e75d4874e0fd215f049908b9eadb3f3cf4d4a9","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-KCEmNXXRS8vlE++ACz1K2u0idUYvvl0h47pjocGWlpPwBfA6rmFuE8uc7MSExn+xA3kkpcBCBDLBDyD8k2RIcg==","shasum":"4e0ba7d2956ad2713b0c51a8bcfc554e517ba84b","tarball":"https://registry.npmjs.org/@donugr/dgradmobbridge/-/dgradmobbridge-0.1.3.tgz","fileCount":27,"unpackedSize":120542,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAuddQyTZyeLgFcd3GFfSnrX6Gr9FbKJmAiBOSV6cQwPAiEAtRPPcszSMlIx02ROw53tdaurQrebM0mnqJb0esH1jWs="}]},"_npmUser":{"name":"donugr","email":"donugr@gmail.com"},"directories":{},"maintainers":[{"name":"donugr","email":"donugr@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dgradmobbridge_0.1.3_1783082319958_0.6302672995421454"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-03T04:11:36.175Z","modified":"2026-07-03T12:38:40.222Z","0.1.1":"2026-07-03T04:11:36.821Z","0.1.2":"2026-07-03T05:58:00.608Z","0.1.3":"2026-07-03T12:38:40.098Z"},"bugs":{"url":"https://github.com/donugr/dgradmobbridge/issues"},"author":{"name":"donugr"},"license":"MIT","homepage":"https://github.com/donugr/dgradmobbridge#readme","keywords":["capacitor","capacitor-plugin","plugin","admob","ads","native-ads","ump","consent","google-ump","gdpr"],"repository":{"type":"git","url":"git+https://github.com/donugr/dgradmobbridge.git"},"description":"Framework-agnostic Capacitor ads facade with standard ads pass-through and a native ads bridge built on top of @capacitor-community/admob.","maintainers":[{"name":"donugr","email":"donugr@gmail.com"}],"readme":"# `@donugr/dgradmobbridge`\n\nFramework-agnostic Capacitor ads facade and native ads bridge.\n\nAndroid-first early public release for a reusable Capacitor AdMob facade and native ads bridge.\n\n## Quick Start\n\nThis is the fastest Android-first example for consumer apps.\n\n### 1. Configure placements once at app startup\n\n```ts\nimport { DgrAdmobBridge } from \"@donugr/dgradmobbridge\";\n\nconst placements = {\n  \"banner.dashboard.footer\": \"ca-app-pub-3940256099942544/6300978111\",\n  \"interstitial.after-save.primary\": \"ca-app-pub-3940256099942544/1033173712\",\n  \"rewarded.export.primary\": \"ca-app-pub-3940256099942544/5224354917\",\n  \"appopen.launch.default\": \"ca-app-pub-3940256099942544/9257395921\",\n  \"native.dashboard.primary\": \"ca-app-pub-3940256099942544/2247696110\",\n};\n\nawait DgrAdmobBridge.configure({\n  enabled: true,\n  testMode: true,\n  placements,\n});\n```\n\nNotes:\n\n- `applicationId` is optional in JS for Android if the app already provides `com.google.android.gms.ads.APPLICATION_ID` in `AndroidManifest.xml`\n- `testMode: true` makes the bridge use Google test ad unit ids internally for all supported formats during integration and testing\n- `testMode: false` makes the bridge use real ad unit ids from your `placements` map or explicit `adUnitId`\n- when `testMode: true`, `placements` may still be provided, but Google test ad unit ids are the ones actually used to request ads\n\nDefault testing example:\n\n```ts\nawait DgrAdmobBridge.configure({\n  enabled: true,\n  testMode: true,\n  placements,\n});\n```\n\nNotes:\n\n- `testMode` is the only runtime switch between testing and live ad-unit behavior\n- Google test mode uses Google demo ad units internally\n- production mode uses ad unit ids from app placements\n- iOS currently keeps contract compatibility but full parity is still in progress\n\n### 2. Banner example\n\n```ts\nawait DgrAdmobBridge.showBanner({\n  placementId: \"banner.dashboard.footer\",\n  position: \"bottom\",\n});\n```\n\nHide or destroy later:\n\n```ts\nawait DgrAdmobBridge.hideBanner(\"banner.dashboard.footer\");\nawait DgrAdmobBridge.destroyBanner(\"banner.dashboard.footer\");\n```\n\n### 3. Interstitial example\n\n```ts\nawait DgrAdmobBridge.preloadInterstitial({\n  placementId: \"interstitial.after-save.primary\",\n});\n\nawait DgrAdmobBridge.showInterstitial(\"interstitial.after-save.primary\");\n```\n\n### 4. Rewarded example\n\n```ts\nawait DgrAdmobBridge.preloadRewarded({\n  placementId: \"rewarded.export.primary\",\n});\n\nawait DgrAdmobBridge.showRewarded(\"rewarded.export.primary\");\n```\n\n### 5. App Open example\n\n```ts\nawait DgrAdmobBridge.preloadAppOpen({\n  placementId: \"appopen.launch.default\",\n});\n\nawait DgrAdmobBridge.showAppOpen(\"appopen.launch.default\");\n```\n\n### 6. Native ads: add a host element in the page\n\n```html\n<div id=\"dashboard-native-slot\"></div>\n```\n\n### 7. Native ads: preload when needed\n\n```ts\nawait DgrAdmobBridge.preloadNative({\n  placementId: \"native.dashboard.primary\",\n  slotId: \"dashboard.primary.slot-1\",\n  hostId: \"dashboard-native-slot\",\n});\n```\n\n### 8. Native ads: optionally calculate `hostRect`, then attach\n\n```ts\nimport { DgrAdmobBridge, buildNativeHostRect } from \"@donugr/dgradmobbridge\";\n\nconst element = document.getElementById(\"dashboard-native-slot\");\n\nif (element) {\n  const hostRect = buildNativeHostRect(element, {\n    anchor: \"top\",\n  });\n\n  await DgrAdmobBridge.attachNative({\n    placementId: \"native.dashboard.primary\",\n    slotId: \"dashboard.primary.slot-1\",\n    hostId: \"dashboard-native-slot\",\n    hostRect,\n  });\n}\n```\n\n### 9. Listen to ad events\n\n```ts\nconst listener = await DgrAdmobBridge.addListener(\"adEvent\", (event) => {\n  console.log(\"adEvent\", event);\n});\n```\n\nExpected phases include:\n\n- `loaded`\n- `failed`\n- `attached`\n- `detached`\n- `preload_start`\n- `preload_reused`\n- `preload_skip_loading`\n- `attach_skipped_same_host`\n- `layout_skipped_same_rect`\n- `clicked`\n- `impression`\n- `shown`\n- `dismissed`\n- `reward_earned`\n\n### 10. Native ads: detach and destroy when leaving the page\n\n```ts\nawait DgrAdmobBridge.detachNative(\"dashboard.primary.slot-1\");\nawait DgrAdmobBridge.destroyNative(\"dashboard.primary.slot-1\");\n\nawait listener.remove();\n```\n\n### 11. Recommended mental model\n\n- `placements` = app-level map of placement keys to ad unit ids\n- `placementId` = which ad inventory to use\n- `slotId` = runtime instance id for one native ad slot\n- `hostId` = logical UI host identity\n- `hostRect` = optional positioning hint for Android native overlay placement\n\n`@donugr/dgradmobbridge` provides one reusable plugin surface for apps that want:\n\n- one ads contract across multiple projects\n- `Android + iOS` contract-first design\n- standard ad formats and UMP powered by `@capacitor-community/admob`\n- custom native ads bridge behavior on top of the community plugin\n\nThis package is intended to become a public npm package and a reusable GitHub plugin repository.\n\n## What This Plugin Does\n\nIt provides one package surface for:\n\n- Google UMP / consent orchestration\n- banner, interstitial, rewarded, and app open pass-through\n- ads enabled / disabled runtime gate\n- native ads bridge contract and lifecycle\n\nCurrent maturity:\n\n- standard ads facade foundation is implemented\n- Android native ads loading and host rendering foundation is implemented\n- native ads host bridge contract is implemented\n- Android native attach now skips identical host re-attach work and clears native resources on activity destroy\n- iOS native ads parity is still in progress\n\n## Installation\n\n```bash\nnpm install @capacitor-community/admob\nnpm install @donugr/dgradmobbridge\nnpx cap sync\n```\n\n`@capacitor-community/admob` is a required peer dependency.\n\nThis package does not bundle its own copy of `@capacitor-community/admob`.\nConsumer apps must install that dependency directly in the app project, then sync native platforms as usual.\n\n## Documentation\n\n- [`CHANGELOG.md`](./CHANGELOG.md)\n- [`docs/android-testing.md`](./docs/android-testing.md)\n- [`docs/native-ads-lifecycle.md`](./docs/native-ads-lifecycle.md)\n- [`RELEASING.md`](./RELEASING.md)\n\n## Android Manifest Requirement\n\nIf `applicationId` is not passed from JS, Android consumer apps should provide:\n\n```xml\n<meta-data\n    android:name=\"com.google.android.gms.ads.APPLICATION_ID\"\n    android:value=\"ca-app-pub-xxxxx~yyyyy\" />\n```\n\nThis allows the plugin to resolve `applicationId` from native app configuration automatically.\n\n## Recommended Config Pattern\n\nRecommended ownership model:\n\n- `applicationId`\n  from native app configuration such as Android manifest\n- `placements`\n  from runtime app config per flavor\n- `adUnitId` passed directly per method call\n  only for explicit overrides or special cases\n\n## Peer Dependencies\n\nRequired peer dependencies:\n\n- `@capacitor/core`\n- `@capacitor-community/admob`\n\nWhy this is a peer dependency instead of a bundled dependency:\n\n- consumer apps stay in control of the actual community AdMob plugin version\n- this package acts as a facade and native-ads bridge, not a full replacement SDK wrapper\n- native build ownership remains explicit inside the consuming app\n\n## Publish Status\n\nThis repository is intended to become a reusable plugin package.\n\nCurrent status:\n\n- package metadata is publish-oriented\n- peer dependency contract is defined\n- TypeScript package build is available\n- native Android and iOS plugin registration is present\n- native ads full production SDK rendering is not finished yet\n\nPackage verification already checked:\n\n- `npm pack --dry-run` passes\n- tarball output is limited to publish-safe files only\n- build output is generated from `prepare`\n\n## Goals\n\n`@donugr/dgradmobbridge` should provide one stable integration surface for:\n\n- consent / Google UMP\n- banner ads\n- interstitial ads\n- rewarded ads\n- app open ads\n- native ads host bridge\n- ads enabled / disabled runtime gate\n- unified event payloads\n\nThe plugin should not contain app-specific ad business rules such as cooldown policy, placement policy per page, or product decisions about when ads may be shown.\n\n## Dependency Policy\n\nIf the peer dependency is missing, `configure()` must fail with a clear runtime error such as:\n\n`DEPENDENCY_MISSING: @capacitor-community/admob`\n\nCurrent runtime message:\n\n`Missing required peer dependency: @capacitor-community/admob. Install it in the app project.`\n\n## High-Level Architecture\n\n### Responsibilities of `@capacitor-community/admob`\n\n- consent / UMP\n- banner\n- interstitial\n- rewarded\n- app open\n\n### Responsibilities of `@donugr/dgradmobbridge`\n\n- unified JS contract\n- dependency validation\n- ads enabled / disabled gate\n- placement config normalization\n- native ads host-based bridge\n- unified event interface\n- safe noads behavior\n\n### Responsibilities of the Consumer App\n\n- when ads are allowed to show\n- placement decisions per screen\n- screen-specific cooldown logic\n- build flavor policy such as ads vs noads\n- UI wrapper components for Vue / React / others\n\n## Contract Baseline\n\n### Public Plugin Name\n\n- Capacitor public plugin name: `DgrAdmobBridge`\n- npm package: `@donugr/dgradmobbridge`\n- Android namespace: `id.donugr.dgradmobbridge`\n- iOS Swift plugin class: `DgrAdmobBridgePlugin`\n\n### Core Types\n\n```ts\ntype AdFormat = \"banner\" | \"interstitial\" | \"rewarded\" | \"native\" | \"app_open\";\n\ntype ConsentStatus = \"unknown\" | \"required\" | \"not_required\" | \"obtained\" | \"denied\";\n\ntype AvailabilityStatus = \"ready\" | \"loading\" | \"not_ready\" | \"disabled\" | \"unsupported\" | \"error\";\n\ntype BridgeResult<T = undefined> = {\n  ok: boolean;\n  status?: AvailabilityStatus;\n  code?: string;\n  message?: string;\n  data?: T;\n};\n```\n\n### Configure Contract\n\n```ts\ntype ConfigureOptions = {\n  enabled: boolean;\n  testMode: boolean;\n  applicationId?: string;\n  placements?: Record<string, string>;\n};\n```\n\nAndroid-first resolve order for `applicationId`:\n\n1. use `configure({ applicationId })` if provided and non-empty\n2. otherwise read `com.google.android.gms.ads.APPLICATION_ID` from the Android app manifest\n3. if neither source provides a valid value, `configure()` must fail clearly\n\n### Consent Contract\n\n```ts\ntype ConsentInfo = {\n  status: ConsentStatus;\n  canRequestAds: boolean;\n  privacyOptionsRequired: boolean;\n};\n```\n\n### Runtime Info Contract\n\n```ts\ntype RuntimeInfo = {\n  platform: \"android\" | \"ios\" | \"web\";\n  enabled: boolean;\n  applicationIdConfigured: boolean;\n  applicationIdSource: \"js\" | \"android_manifest\" | \"ios_plist\" | \"missing\";\n};\n```\n\nCurrent implementation status:\n\n- Android returns real `applicationIdConfigured` and `applicationIdSource`\n- iOS parity for this field is still pending\n\n### Banner Contract\n\n```ts\ntype BannerOptions = {\n  placementId: string;\n  containerId?: string;\n  position?: \"top\" | \"bottom\";\n  autoRefreshIntervalMs?: number;\n};\n```\n\n### Fullscreen Contract\n\n```ts\ntype FullscreenOptions = {\n  placementId: string;\n};\n```\n\n### Native Contract\n\n```ts\ntype NativeHostRect = {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n  anchor?: \"top\" | \"bottom\";\n};\n\ntype NativeOptions = {\n  placementId: string;\n  slotId: string;\n  hostId: string;\n  adUnitId?: string;\n  ttlMs?: number;\n  hostRect?: NativeHostRect;\n};\n```\n\n### DOM Host Helper\n\nThis package also exports a framework-agnostic helper for DOM-based apps:\n\n```ts\nimport { buildNativeHostRect } from \"@donugr/dgradmobbridge\";\n```\n\nUse it to translate a DOM element's bounding box into an optional `hostRect` payload for native placement.\n\n## Public Method Blueprint\n\n```ts\nconfigure(options: ConfigureOptions): Promise<BridgeResult>\ngetRuntimeInfo(): Promise<BridgeResult<{ platform: \"android\" | \"ios\" | \"web\"; enabled: boolean }>>\n\nrequestConsentInfo(): Promise<BridgeResult<ConsentInfo>>\nshowConsentFormIfRequired(): Promise<BridgeResult<ConsentInfo>>\nshowPrivacyOptionsForm(): Promise<BridgeResult<ConsentInfo>>\ngetConsentStatus(): Promise<BridgeResult<ConsentInfo>>\nresetConsentForTesting(): Promise<BridgeResult>\n\nloadBanner(options: BannerOptions): Promise<BridgeResult>\nshowBanner(options: BannerOptions): Promise<BridgeResult>\nhideBanner(placementId: string): Promise<BridgeResult>\ndestroyBanner(placementId: string): Promise<BridgeResult>\n\npreloadInterstitial(options: FullscreenOptions): Promise<BridgeResult>\nisInterstitialReady(placementId: string): Promise<BridgeResult<{ ready: boolean }>>\nshowInterstitial(placementId: string): Promise<BridgeResult>\n\npreloadRewarded(options: FullscreenOptions): Promise<BridgeResult>\nisRewardedReady(placementId: string): Promise<BridgeResult<{ ready: boolean }>>\nshowRewarded(placementId: string): Promise<BridgeResult>\n\npreloadAppOpen(options: FullscreenOptions): Promise<BridgeResult>\nisAppOpenReady(placementId: string): Promise<BridgeResult<{ ready: boolean }>>\nshowAppOpen(placementId: string): Promise<BridgeResult>\n\npreloadNative(options: NativeOptions): Promise<BridgeResult>\nisNativeReady(slotId: string): Promise<BridgeResult<{ ready: boolean }>>\nattachNative(options: NativeOptions): Promise<BridgeResult>\ndetachNative(slotId: string): Promise<BridgeResult>\ndestroyNative(slotId: string): Promise<BridgeResult>\nrefreshNative(options: NativeOptions): Promise<BridgeResult>\n\nclearAll(): Promise<BridgeResult>\n```\n\n## Event Blueprint\n\n```ts\ntype AdEvent = {\n  format: AdFormat;\n  placementId: string;\n  slotId?: string;\n  phase:\n    | \"loaded\"\n    | \"failed\"\n    | \"shown\"\n    | \"dismissed\"\n    | \"clicked\"\n    | \"impression\"\n    | \"reward_earned\"\n    | \"attached\"\n    | \"detached\"\n    | \"consent_updated\";\n  code?: string;\n  message?: string;\n};\n```\n\nAll platforms should emit the same event shape.\n\n## Behavior Matrix\n\n### Banner\n\n- supports `load`, `show`, `hide`, `destroy`\n- may support timer-based auto refresh\n- default auto refresh should be off\n\n### Interstitial\n\n- supports preload and readiness checks\n- no timer-based visual auto refresh\n- app layer decides when it may be shown\n\n### Rewarded\n\n- same preload pattern as interstitial\n- must emit reward-earned event explicitly\n\n### App Open\n\n- preload-based\n- app layer controls whether showing is allowed\n- should be guarded by startup/resume policy\n\n### Native Ads\n\n- host-based, not Vue-specific payload-first rendering\n- attach to a host container by `hostId`\n- supports `slotId` lifecycle\n- refresh should be explicit or TTL-driven\n- no visual timer swap while visible\n- optional `hostRect` may be supplied for more precise native overlay placement\n\n## Placement Naming Convention\n\nUse readable, stable placement names:\n\n- `banner.dashboard.footer`\n- `interstitial.after-save-bahan`\n- `rewarded.export.report`\n- `appopen.launch.default`\n- `native.dashboard.primary`\n\nUse more technical slot identifiers only for native host instances:\n\n- `dashboard.primary.slot-1`\n- `report.inline.slot-1`\n- `feed.inventory.row-6`\n\n## Consent Flow\n\nRecommended startup order for ads-enabled builds:\n\n1. `configure()`\n2. `requestConsentInfo()`\n3. `showConsentFormIfRequired()`\n4. `getConsentStatus()`\n5. if `canRequestAds === true`, allow preloading ads\n\nIf the build or runtime is noads:\n\n- `configure({ enabled: false, ... })`\n- all ad-loading methods return `disabled`\n- consent flow should not block app startup\n\n## Installation Strategy\n\nThis package should not silently bundle its own copy of `@capacitor-community/admob`.\n\nThe dependency loader uses a bundler-friendly literal import path so consuming apps can resolve the peer dependency without app-specific Vite patching in common setups.\n\n## Native Host Positioning\n\nCurrent Android behavior:\n\n- if `hostRect` is not provided, native ads use a safe overlay fallback near the bottom of the screen\n- if `hostRect` is provided, Android uses that rectangle to position the native host container more precisely\n- `hostId` still remains required as the logical slot identity\n\nExample:\n\n```ts\nimport { DgrAdmobBridge, buildNativeHostRect } from \"@donugr/dgradmobbridge\";\n\nconst element = document.getElementById(\"dashboard-native-slot\");\n\nif (element) {\n  const hostRect = buildNativeHostRect(element, {\n    anchor: \"top\",\n  });\n\n  await DgrAdmobBridge.attachNative({\n    placementId: \"native.dashboard.primary\",\n    slotId: \"dashboard.primary.slot-1\",\n    hostId: \"dashboard-native-slot\",\n    hostRect,\n  });\n}\n```\n\nNotes:\n\n- this helper is optional\n- it is framework-agnostic and works with Vue, React, or plain DOM\n- exact visual alignment still depends on the WebView/native overlay model of the consumer app\n\n## Package Structure\n\nRepository structure:\n\n- `src/`\n  JS/TS facade and shared contract\n- `android/`\n  Android plugin source\n- `ios/`\n  iOS plugin source\n- `README.md`\n  public GitHub and npm landing page\n- `package.json`\n  npm metadata, peer dependency policy, publish contract\n- `DgrAdmobBridge.podspec`\n  iOS CocoaPods publish metadata\n\nPublish tarball structure from `npm pack --dry-run`:\n\n- `android/build.gradle`\n- `android/src/main/**`\n- `ios/**`\n- `dist/**`\n- `DgrAdmobBridge.podspec`\n- `LICENSE`\n- `README.md`\n- `package.json`\n\nFiles intentionally excluded from publish package:\n\n- `node_modules/`\n- `.git/`\n- `.github/`\n- local native build outputs\n- raw repository-only clutter\n\n## Current Status\n\nCurrent state:\n\n- package identity defined\n- dependency policy defined\n- public contract defined\n- TypeScript facade implemented\n- runtime dependency validation implemented\n- pass-through surface for `@capacitor-community/admob` standard ads implemented\n- Android native plugin registration implemented\n- Android native ad loading implemented\n- Android native host view binding implemented\n- iOS native plugin registration implemented\n- native slot lifecycle placeholder bridge implemented for iOS\n- package TypeScript build verified\n- repository-ready `.gitignore` added\n\nWhat is already usable now:\n\n- one import surface for the plugin package\n- dependency guard for missing `@capacitor-community/admob`\n- ads enabled / disabled gate\n- pass-through design for consent, banner, interstitial, rewarded, and app open\n- Android native ads preload / attach / detach / destroy / refresh flow\n- optional DOM-to-native `hostRect` helper for browser-driven positioning\n\nWhat is not fully production-complete yet:\n\n- full iOS native ads rendering parity\n- exact DOM-backed host alignment strategy for every consumer app layout\n- full device QA with installed peer dependency and native platform builds\n\n## Current Limitations\n\nStandard ads:\n\n- the facade is implemented against expected `@capacitor-community/admob` APIs\n- final runtime verification still depends on installing the peer dependency in the consuming app\n\nNative ads:\n\n- Android can now load, bind, and attach native ads with a host overlay strategy\n- `preloadNative`, `attachNative`, `detachNative`, and `refreshNative` are wired with consistent result shapes and events\n- iOS native ads still need parity work\n- some consumer apps may still want custom `hostRect` measurement and alignment tuning\n\nThis means the package is already a stronger Android-first foundation for native ads, but it is not yet final cross-platform production-native integration.\n","readmeFilename":"README.md"}