react-native-buzzvil-ad 0.1.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.
Files changed (62) hide show
  1. package/Buzzvil.podspec +26 -0
  2. package/LICENSE +20 -0
  3. package/README.md +58 -0
  4. package/android/build.gradle +76 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/com/buzzvil/BuzzvilModule.kt +90 -0
  7. package/android/src/main/java/com/buzzvil/BuzzvilNativeAdView.kt +250 -0
  8. package/android/src/main/java/com/buzzvil/BuzzvilNativeAdViewManager.kt +62 -0
  9. package/android/src/main/java/com/buzzvil/BuzzvilPackage.kt +37 -0
  10. package/android/src/main/res/layout/buzzvil_native_ad_banner.xml +68 -0
  11. package/android/src/main/res/layout/buzzvil_native_ad_card.xml +39 -0
  12. package/ios/Buzzvil.h +5 -0
  13. package/ios/Buzzvil.mm +100 -0
  14. package/ios/BuzzvilNativeAdView.h +14 -0
  15. package/ios/BuzzvilNativeAdView.mm +423 -0
  16. package/lib/module/BuzzvilNativeAdView.js +16 -0
  17. package/lib/module/BuzzvilNativeAdView.js.map +1 -0
  18. package/lib/module/BuzzvilNativeAdView.native.js +42 -0
  19. package/lib/module/BuzzvilNativeAdView.native.js.map +1 -0
  20. package/lib/module/BuzzvilNativeAdViewNativeComponent.ts +22 -0
  21. package/lib/module/NativeBuzzvil.js +32 -0
  22. package/lib/module/NativeBuzzvil.js.map +1 -0
  23. package/lib/module/buzzvil.js +25 -0
  24. package/lib/module/buzzvil.js.map +1 -0
  25. package/lib/module/buzzvil.native.js +64 -0
  26. package/lib/module/buzzvil.native.js.map +1 -0
  27. package/lib/module/index.js +5 -0
  28. package/lib/module/index.js.map +1 -0
  29. package/lib/module/layout.js +39 -0
  30. package/lib/module/layout.js.map +1 -0
  31. package/lib/module/package.json +1 -0
  32. package/lib/module/types.js +2 -0
  33. package/lib/module/types.js.map +1 -0
  34. package/lib/typescript/package.json +1 -0
  35. package/lib/typescript/src/BuzzvilNativeAdView.d.ts +3 -0
  36. package/lib/typescript/src/BuzzvilNativeAdView.d.ts.map +1 -0
  37. package/lib/typescript/src/BuzzvilNativeAdView.native.d.ts +196 -0
  38. package/lib/typescript/src/BuzzvilNativeAdView.native.d.ts.map +1 -0
  39. package/lib/typescript/src/BuzzvilNativeAdViewNativeComponent.d.ts +25 -0
  40. package/lib/typescript/src/BuzzvilNativeAdViewNativeComponent.d.ts.map +1 -0
  41. package/lib/typescript/src/NativeBuzzvil.d.ts +72 -0
  42. package/lib/typescript/src/NativeBuzzvil.d.ts.map +1 -0
  43. package/lib/typescript/src/buzzvil.d.ts +7 -0
  44. package/lib/typescript/src/buzzvil.d.ts.map +1 -0
  45. package/lib/typescript/src/buzzvil.native.d.ts +25 -0
  46. package/lib/typescript/src/buzzvil.native.d.ts.map +1 -0
  47. package/lib/typescript/src/index.d.ts +5 -0
  48. package/lib/typescript/src/index.d.ts.map +1 -0
  49. package/lib/typescript/src/layout.d.ts +6 -0
  50. package/lib/typescript/src/layout.d.ts.map +1 -0
  51. package/lib/typescript/src/types.d.ts +44 -0
  52. package/lib/typescript/src/types.d.ts.map +1 -0
  53. package/package.json +159 -0
  54. package/src/BuzzvilNativeAdView.native.tsx +48 -0
  55. package/src/BuzzvilNativeAdView.tsx +12 -0
  56. package/src/BuzzvilNativeAdViewNativeComponent.ts +22 -0
  57. package/src/NativeBuzzvil.ts +76 -0
  58. package/src/buzzvil.native.tsx +65 -0
  59. package/src/buzzvil.tsx +29 -0
  60. package/src/index.tsx +10 -0
  61. package/src/layout.ts +21 -0
  62. package/src/types.ts +45 -0
@@ -0,0 +1,25 @@
1
+ import type { BuzzvilUser, BenefitHubOptions } from './types.js';
2
+ /**
3
+ * Native (iOS/Android) implementation of the public Buzzvil API. Maps the
4
+ * friendly types in `./types` onto the primitive-only native spec, applying
5
+ * the sentinel contract documented in `./NativeBuzzvil`.
6
+ */
7
+ /** Initialize the BuzzBenefit SDK. Call once, before any other method. */
8
+ export declare function initialize(appId: string): void;
9
+ /**
10
+ * Dev-only sanity checks for `userId`. Buzzvil requires a non-PII, stable,
11
+ * ASCII identifier (≤255 chars) — not an email or login id. Returns a list of
12
+ * human-readable warnings (empty when the id looks fine). Pure: `login` logs
13
+ * these via `console.warn` only under `__DEV__`; it never alters behavior or
14
+ * blocks the call (the SDK is the source of truth on acceptance).
15
+ */
16
+ export declare function userIdWarnings(userId: string): string[];
17
+ /** Log a user in. Resolves on success, rejects on SDK failure. */
18
+ export declare function login(user: BuzzvilUser): Promise<void>;
19
+ /** Log the current user out. */
20
+ export declare function logout(): void;
21
+ /** Whether a user is currently logged in. */
22
+ export declare function isLoggedIn(): Promise<boolean>;
23
+ /** Present the BenefitHub (offerwall) over the current screen. */
24
+ export declare function showBenefitHub(options?: BenefitHubOptions): void;
25
+ //# sourceMappingURL=buzzvil.native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buzzvil.native.d.ts","sourceRoot":"","sources":["../../../src/buzzvil.native.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAS,CAAC;AAE9D;;;;GAIG;AAEH,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBvD;AAED,kEAAkE;AAClE,wBAAgB,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtD;AAED,gCAAgC;AAChC,wBAAgB,MAAM,IAAI,IAAI,CAE7B;AAED,6CAA6C;AAC7C,wBAAgB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAE7C;AAED,kEAAkE;AAClE,wBAAgB,cAAc,CAAC,OAAO,GAAE,iBAAsB,GAAG,IAAI,CAEpE"}
@@ -0,0 +1,5 @@
1
+ export { initialize, login, logout, isLoggedIn, showBenefitHub, } from './buzzvil';
2
+ export type { BuzzvilUser, BuzzvilGender, BenefitHubOptions } from './types.js';
3
+ export { BuzzvilNativeAdView } from './BuzzvilNativeAdView';
4
+ export type { BuzzvilNativeAdLayout, BuzzvilNativeAdViewProps } from './types.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,KAAK,EACL,MAAM,EACN,UAAU,EACV,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAS,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,YAAS,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** Resolve the default size for a layout; unknown/undefined → `300x250`. */
2
+ export declare function sizeForLayout(layout?: string): {
3
+ width: number;
4
+ height: number;
5
+ } | undefined;
6
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/layout.ts"],"names":[],"mappings":"AAiBA,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM;WATF,MAAM;YAAU,MAAM;cAWhE"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Public, friendly types for the Buzzvil wrapper. These are the types
3
+ * consumers see; the native spec (`./NativeBuzzvil`) uses primitives only and
4
+ * the wrapper (`./buzzvil.native.tsx`) maps between the two.
5
+ */
6
+ /** Optional demographic hint used by Buzzvil for ad targeting. */
7
+ export type BuzzvilGender = 'MALE' | 'FEMALE';
8
+ /** A Buzzvil user. Only `userId` is required; the rest improve targeting. */
9
+ export interface BuzzvilUser {
10
+ /** Non-identifiable, persistent user id. ASCII, max 255 chars. */
11
+ userId: string;
12
+ gender?: BuzzvilGender;
13
+ /** 4-digit birth year, e.g. `1990`. */
14
+ birthYear?: number;
15
+ }
16
+ /** Options for presenting the BenefitHub (offerwall). */
17
+ export interface BenefitHubOptions {
18
+ /** BenefitHub page number from the Buzzvil admin (advanced routing). */
19
+ routePath?: string;
20
+ /** Open directly on the history/earnings page instead of the default hub. */
21
+ showHistory?: boolean;
22
+ }
23
+ /** Supported Native-ad layout sizes (width x height in dp). */
24
+ export type BuzzvilNativeAdLayout = '320x50' | '320x100' | '320x130' | '300x250' | '320x480';
25
+ /** Friendly props for the `BuzzvilNativeAdView` Fabric component. */
26
+ export interface BuzzvilNativeAdViewProps {
27
+ unitId: string;
28
+ layout?: BuzzvilNativeAdLayout;
29
+ style?: import('react-native').StyleProp<import('react-native').ViewStyle>;
30
+ onAdLoaded?: (e: {
31
+ width: number;
32
+ height: number;
33
+ }) => void;
34
+ onAdFailed?: (e: {
35
+ code: string;
36
+ message: string;
37
+ }) => void;
38
+ onAdClicked?: () => void;
39
+ onImpressed?: () => void;
40
+ onRewarded?: (e: {
41
+ success: boolean;
42
+ }) => void;
43
+ }
44
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE9C,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,+DAA+D;AAC/D,MAAM,MAAM,qBAAqB,GAC7B,QAAQ,GACR,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,CAAC;AAEd,qEAAqE;AACrE,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,cAAc,EAAE,SAAS,CAAC,OAAO,cAAc,EAAE,SAAS,CAAC,CAAC;IAC3E,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5D,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAChD"}
package/package.json ADDED
@@ -0,0 +1,159 @@
1
+ {
2
+ "name": "react-native-buzzvil-ad",
3
+ "version": "0.1.0",
4
+ "description": "Unofficial, community-maintained React Native wrapper for the Buzzvil BuzzBenefit SDK (Android & iOS). Not affiliated with, endorsed by, or supported by Buzzvil.",
5
+ "main": "./lib/module/index.js",
6
+ "types": "./lib/typescript/src/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "source": "./src/index.tsx",
10
+ "types": "./lib/typescript/src/index.d.ts",
11
+ "default": "./lib/module/index.js"
12
+ },
13
+ "./package.json": "./package.json"
14
+ },
15
+ "files": [
16
+ "src",
17
+ "lib",
18
+ "android",
19
+ "ios",
20
+ "cpp",
21
+ "*.podspec",
22
+ "react-native.config.js",
23
+ "!ios/build",
24
+ "!android/build",
25
+ "!android/gradle",
26
+ "!android/gradlew",
27
+ "!android/gradlew.bat",
28
+ "!android/local.properties",
29
+ "!**/__tests__",
30
+ "!**/__fixtures__",
31
+ "!**/__mocks__",
32
+ "!**/.*"
33
+ ],
34
+ "scripts": {
35
+ "example": "yarn workspace react-native-buzzvil-example",
36
+ "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
37
+ "prepare": "bob build",
38
+ "typecheck": "tsc",
39
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
40
+ "test": "jest",
41
+ "web": "vite",
42
+ "build:web": "vite build"
43
+ },
44
+ "keywords": [
45
+ "react-native",
46
+ "ios",
47
+ "android"
48
+ ],
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/AndrewDongminYoo/react-native-buzzvil.git"
52
+ },
53
+ "author": "Dongmin, Yu <ydm2790@gmail.com> (https://github.com/AndrewDongminYoo)",
54
+ "license": "MIT",
55
+ "bugs": {
56
+ "url": "https://github.com/AndrewDongminYoo/react-native-buzzvil/issues"
57
+ },
58
+ "homepage": "https://github.com/AndrewDongminYoo/react-native-buzzvil#readme",
59
+ "publishConfig": {
60
+ "access": "public",
61
+ "registry": "https://registry.npmjs.org/"
62
+ },
63
+ "devDependencies": {
64
+ "@eslint/compat": "^2.1.0",
65
+ "@eslint/eslintrc": "^3.3.5",
66
+ "@eslint/js": "^10.0.1",
67
+ "@jest/globals": "^30.0.0",
68
+ "@react-native/babel-preset": "0.85.0",
69
+ "@react-native/eslint-config": "0.85.0",
70
+ "@react-native/jest-preset": "0.85.0",
71
+ "@types/react": "^19.2.0",
72
+ "del-cli": "^7.0.0",
73
+ "eslint": "^9.39.4",
74
+ "eslint-config-prettier": "^10.1.8",
75
+ "eslint-plugin-ft-flow": "^3.0.11",
76
+ "eslint-plugin-prettier": "^5.5.6",
77
+ "jest": "^30.3.0",
78
+ "prettier": "^3.8.3",
79
+ "react": "19.2.3",
80
+ "react-native": "0.85.0",
81
+ "react-native-builder-bob": "^0.42.1",
82
+ "react-native-web": "~0.21.2",
83
+ "turbo": "^2.9.16",
84
+ "typescript": "^6.0.3"
85
+ },
86
+ "peerDependencies": {
87
+ "react": "*",
88
+ "react-native": "*"
89
+ },
90
+ "resolutions": {
91
+ "jest": "30.4.1",
92
+ "jest-cli": "30.4.1",
93
+ "@jest/core": "30.4.1",
94
+ "jest-runtime": "30.4.1",
95
+ "jest-mock": "30.4.1",
96
+ "jest-environment-node": "30.4.1"
97
+ },
98
+ "workspaces": [
99
+ "example"
100
+ ],
101
+ "packageManager": "yarn@4.11.0",
102
+ "react-native-builder-bob": {
103
+ "source": "src",
104
+ "output": "lib",
105
+ "targets": [
106
+ [
107
+ "module",
108
+ {
109
+ "esm": true
110
+ }
111
+ ],
112
+ [
113
+ "typescript",
114
+ {
115
+ "project": "tsconfig.build.json"
116
+ }
117
+ ]
118
+ ]
119
+ },
120
+ "codegenConfig": {
121
+ "name": "BuzzvilSpec",
122
+ "type": "all",
123
+ "jsSrcsDir": "src",
124
+ "android": {
125
+ "javaPackageName": "com.buzzvil"
126
+ },
127
+ "ios": {
128
+ "components": {
129
+ "BuzzvilNativeAdView": {
130
+ "className": "BuzzvilNativeAdView"
131
+ }
132
+ }
133
+ }
134
+ },
135
+ "prettier": {
136
+ "quoteProps": "consistent",
137
+ "singleQuote": true,
138
+ "tabWidth": 2,
139
+ "trailingComma": "es5",
140
+ "useTabs": false
141
+ },
142
+ "jest": {
143
+ "preset": "@react-native/jest-preset",
144
+ "modulePathIgnorePatterns": [
145
+ "<rootDir>/example/node_modules",
146
+ "<rootDir>/lib/"
147
+ ]
148
+ },
149
+ "create-react-native-library": {
150
+ "type": "fabric-view",
151
+ "languages": "kotlin-objc",
152
+ "tools": [
153
+ "eslint",
154
+ "jest",
155
+ "vite"
156
+ ],
157
+ "version": "0.62.2"
158
+ }
159
+ }
@@ -0,0 +1,48 @@
1
+ import NativeComponent from './BuzzvilNativeAdViewNativeComponent';
2
+ import { sizeForLayout } from './layout';
3
+ import type { BuzzvilNativeAdViewProps } from './types';
4
+
5
+ export { sizeForLayout };
6
+
7
+ const DEFAULT_LAYOUT = '300x250';
8
+
9
+ export function toNativeProps(props: BuzzvilNativeAdViewProps) {
10
+ const {
11
+ layout,
12
+ onAdLoaded,
13
+ onAdFailed,
14
+ onAdClicked,
15
+ onImpressed,
16
+ onRewarded,
17
+ ...rest
18
+ } = props;
19
+ return {
20
+ ...rest,
21
+ layout: layout ?? DEFAULT_LAYOUT,
22
+ onAdLoaded: onAdLoaded
23
+ ? (e: { nativeEvent: { width: number; height: number } }) =>
24
+ onAdLoaded(e.nativeEvent)
25
+ : undefined,
26
+ onAdFailed: onAdFailed
27
+ ? (e: { nativeEvent: { code: string; message: string } }) =>
28
+ onAdFailed(e.nativeEvent)
29
+ : undefined,
30
+ // No payload — pass the friendly handler straight through (it ignores the
31
+ // native event arg). Avoids an empty wrapper that could mislead a future
32
+ // contributor copying the pattern for a payload-carrying event.
33
+ onAdClicked,
34
+ onImpressed,
35
+ onRewarded: onRewarded
36
+ ? (e: { nativeEvent: { success: boolean } }) => onRewarded(e.nativeEvent)
37
+ : undefined,
38
+ };
39
+ }
40
+
41
+ export function BuzzvilNativeAdView(props: BuzzvilNativeAdViewProps) {
42
+ const native = toNativeProps(props);
43
+ const size = sizeForLayout(props.layout);
44
+ // Apply the inventory size as a DEFAULT style; the consumer's `style` is
45
+ // last in the array, so it overrides. `style` is set once here (the explicit
46
+ // prop wins over the one carried in `native`'s spread).
47
+ return <NativeComponent {...(native as any)} style={[size, props.style]} />;
48
+ }
@@ -0,0 +1,12 @@
1
+ import { View } from 'react-native';
2
+ import { sizeForLayout } from './layout';
3
+ import type { BuzzvilNativeAdViewProps } from './types';
4
+
5
+ export function BuzzvilNativeAdView({
6
+ layout,
7
+ style,
8
+ }: BuzzvilNativeAdViewProps) {
9
+ // Buzzvil native ads are not available on web; render nothing visible, but
10
+ // reserve the same box as native (consumer `style` overrides the default).
11
+ return <View style={[sizeForLayout(layout), style]} />;
12
+ }
@@ -0,0 +1,22 @@
1
+ import { codegenNativeComponent, type ViewProps } from 'react-native';
2
+ import type { CodegenTypes } from 'react-native';
3
+
4
+ // Flat primitive payloads — codegen events cannot carry nested objects/enums.
5
+ type AdLoadedEvent = Readonly<{
6
+ width: CodegenTypes.Double;
7
+ height: CodegenTypes.Double;
8
+ }>;
9
+ type AdFailedEvent = Readonly<{ code: string; message: string }>;
10
+ type RewardedEvent = Readonly<{ success: boolean }>;
11
+
12
+ export interface NativeProps extends ViewProps {
13
+ unitId: string;
14
+ layout?: string; // friendly union + default live in the JS wrapper; codegen sees a plain string
15
+ onAdLoaded?: CodegenTypes.DirectEventHandler<AdLoadedEvent>;
16
+ onAdFailed?: CodegenTypes.DirectEventHandler<AdFailedEvent>;
17
+ onAdClicked?: CodegenTypes.DirectEventHandler<Readonly<{}>>;
18
+ onImpressed?: CodegenTypes.DirectEventHandler<Readonly<{}>>;
19
+ onRewarded?: CodegenTypes.DirectEventHandler<RewardedEvent>;
20
+ }
21
+
22
+ export default codegenNativeComponent<NativeProps>('BuzzvilNativeAdView');
@@ -0,0 +1,76 @@
1
+ import { TurboModuleRegistry, type TurboModule } from 'react-native';
2
+
3
+ /**
4
+ * TurboModule spec for the native `Buzzvil` module — a thin bridge over
5
+ * Buzzvil's BuzzBenefit v6 SDKs (Android / iOS).
6
+ *
7
+ * This file is the **source of truth**: codegen generates the native
8
+ * interfaces from it. The codegen type system is restricted, so the spec
9
+ * intentionally uses **primitives only** — no optional fields, no object
10
+ * params, no enums/unions. Friendly types (optional fields, the `'MALE' |
11
+ * 'FEMALE'` gender union) live in `./types` and are applied in the JS
12
+ * wrapper (`./buzzvil.native.tsx`).
13
+ *
14
+ * ## Sentinel contract (MUST be interpreted identically by both native impls)
15
+ *
16
+ * Because the spec has no optionals, the JS wrapper encodes "not provided"
17
+ * as sentinel values. `BuzzvilModule.kt` and `Buzzvil.mm` must treat them
18
+ * the same way or the platforms will silently diverge:
19
+ *
20
+ * - `gender`: `'MALE'` or `'FEMALE'`. **Empty string `''` → do not set gender**
21
+ * (pass `null` to the native user builder).
22
+ * - `birthYear`: a 4-digit year. **`0` → do not set birth year** (pass `null`).
23
+ * - `routePath`: a BenefitHub page number from the Buzzvil admin. **`''` → no
24
+ * route path** (open the default hub page).
25
+ * - `showHistory`: `true` → open the BenefitHub history/earnings page
26
+ * (Android `BuzzBenefitHubPage.HISTORY` / iOS `.history` query params).
27
+ */
28
+ export interface Spec extends TurboModule {
29
+ /**
30
+ * Initialize the BuzzBenefit SDK with the app's Buzzvil app id.
31
+ *
32
+ * - iOS: `BuzzBenefit.shared.initialize(with: BuzzBenefitConfig.Builder(appId:).build())`.
33
+ * - Android: `BuzzvilSdk.initialize(application, BuzzBenefitConfig.Builder(appId).build())`.
34
+ *
35
+ * NOTE (verify at native-impl time): the Android SDK initializes with the
36
+ * `Application` instance and the docs recommend `Application.onCreate()`
37
+ * timing. JS-driven init must pass `reactContext.applicationContext as
38
+ * Application` and run before any `login`/`showBenefitHub` call. If the
39
+ * Android SDK turns out to require manifest/Application-level setup (as the
40
+ * AdPopcorn wrapper's `setAppKey` does), this becomes iOS-effective with an
41
+ * Android no-op — confirm against the running SDK before shipping.
42
+ */
43
+ initialize(appId: string): void;
44
+
45
+ /**
46
+ * Log a user into the SDK. Resolves on success, rejects on failure.
47
+ *
48
+ * See the sentinel contract above for `gender` / `birthYear`.
49
+ *
50
+ * - iOS: `BuzzBenefit.shared.login(with:onSuccess:onFailure:)`.
51
+ * - Android: `BuzzvilSdk.login(BuzzvilSdkUser(...), BuzzvilSdkLoginListener)`.
52
+ *
53
+ * @param userId Non-identifiable, persistent user id. ASCII, max 255 chars.
54
+ * @param gender `'MALE'` | `'FEMALE'` | `''` (unset).
55
+ * @param birthYear 4-digit year, or `0` (unset).
56
+ */
57
+ login(userId: string, gender: string, birthYear: number): Promise<void>;
58
+
59
+ /** Log the current user out. iOS/Android: `logout()`. */
60
+ logout(): void;
61
+
62
+ /** Whether a user is currently logged in. iOS `isLoggedIn()` / Android `isLoggedIn`. */
63
+ isLoggedIn(): Promise<boolean>;
64
+
65
+ /**
66
+ * Present the BenefitHub (offerwall) over the current screen.
67
+ *
68
+ * - iOS: `BuzzBenefitHub().show(on: currentViewController)`.
69
+ * - Android: `BuzzBenefitHub.show(currentActivity, config)`.
70
+ *
71
+ * See the sentinel contract above for `routePath` / `showHistory`.
72
+ */
73
+ showBenefitHub(routePath: string, showHistory: boolean): void;
74
+ }
75
+
76
+ export default TurboModuleRegistry.getEnforcing<Spec>('Buzzvil');
@@ -0,0 +1,65 @@
1
+ import Buzzvil from './NativeBuzzvil';
2
+ import type { BuzzvilUser, BenefitHubOptions } from './types';
3
+
4
+ /**
5
+ * Native (iOS/Android) implementation of the public Buzzvil API. Maps the
6
+ * friendly types in `./types` onto the primitive-only native spec, applying
7
+ * the sentinel contract documented in `./NativeBuzzvil`.
8
+ */
9
+
10
+ /** Initialize the BuzzBenefit SDK. Call once, before any other method. */
11
+ export function initialize(appId: string): void {
12
+ Buzzvil.initialize(appId);
13
+ }
14
+
15
+ /**
16
+ * Dev-only sanity checks for `userId`. Buzzvil requires a non-PII, stable,
17
+ * ASCII identifier (≤255 chars) — not an email or login id. Returns a list of
18
+ * human-readable warnings (empty when the id looks fine). Pure: `login` logs
19
+ * these via `console.warn` only under `__DEV__`; it never alters behavior or
20
+ * blocks the call (the SDK is the source of truth on acceptance).
21
+ */
22
+ export function userIdWarnings(userId: string): string[] {
23
+ const warnings: string[] = [];
24
+ if (!userId) {
25
+ warnings.push('userId is empty.');
26
+ return warnings;
27
+ }
28
+ if (userId.includes('@')) {
29
+ warnings.push(
30
+ 'userId looks like an email — Buzzvil requires a non-PII, stable identifier (not an email/login id); ads may be rejected.'
31
+ );
32
+ }
33
+ if (userId.length > 255) {
34
+ warnings.push('userId exceeds 255 characters.');
35
+ }
36
+ if ([...userId].some((ch) => ch.charCodeAt(0) > 127)) {
37
+ warnings.push('userId should be ASCII.');
38
+ }
39
+ return warnings;
40
+ }
41
+
42
+ /** Log a user in. Resolves on success, rejects on SDK failure. */
43
+ export function login(user: BuzzvilUser): Promise<void> {
44
+ if (__DEV__) {
45
+ for (const message of userIdWarnings(user.userId)) {
46
+ console.warn(`[buzzvil] login: ${message}`);
47
+ }
48
+ }
49
+ return Buzzvil.login(user.userId, user.gender ?? '', user.birthYear ?? 0);
50
+ }
51
+
52
+ /** Log the current user out. */
53
+ export function logout(): void {
54
+ Buzzvil.logout();
55
+ }
56
+
57
+ /** Whether a user is currently logged in. */
58
+ export function isLoggedIn(): Promise<boolean> {
59
+ return Buzzvil.isLoggedIn();
60
+ }
61
+
62
+ /** Present the BenefitHub (offerwall) over the current screen. */
63
+ export function showBenefitHub(options: BenefitHubOptions = {}): void {
64
+ Buzzvil.showBenefitHub(options.routePath ?? '', options.showHistory ?? false);
65
+ }
@@ -0,0 +1,29 @@
1
+ import type { BuzzvilUser, BenefitHubOptions } from './types';
2
+
3
+ /**
4
+ * Web fallback. Buzzvil's BuzzBenefit SDKs are mobile-only, so every method
5
+ * throws **at call time** (never at import time — importing must not break the
6
+ * web bundle). The `.native.tsx` counterpart is used on iOS/Android.
7
+ */
8
+
9
+ const UNSUPPORTED = 'react-native-buzzvil is not supported on web.';
10
+
11
+ export function initialize(_appId: string): void {
12
+ throw new Error(UNSUPPORTED);
13
+ }
14
+
15
+ export function login(_user: BuzzvilUser): Promise<void> {
16
+ return Promise.reject(new Error(UNSUPPORTED));
17
+ }
18
+
19
+ export function logout(): void {
20
+ throw new Error(UNSUPPORTED);
21
+ }
22
+
23
+ export function isLoggedIn(): Promise<boolean> {
24
+ return Promise.reject(new Error(UNSUPPORTED));
25
+ }
26
+
27
+ export function showBenefitHub(_options: BenefitHubOptions = {}): void {
28
+ throw new Error(UNSUPPORTED);
29
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,10 @@
1
+ export {
2
+ initialize,
3
+ login,
4
+ logout,
5
+ isLoggedIn,
6
+ showBenefitHub,
7
+ } from './buzzvil';
8
+ export type { BuzzvilUser, BuzzvilGender, BenefitHubOptions } from './types';
9
+ export { BuzzvilNativeAdView } from './BuzzvilNativeAdView';
10
+ export type { BuzzvilNativeAdLayout, BuzzvilNativeAdViewProps } from './types';
package/src/layout.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Default inventory sizes for the Native-ad layout variants, shared by the
3
+ * native and web `BuzzvilNativeAdView` so the box matches on every platform.
4
+ *
5
+ * Under Fabric the component's frame comes from the JS shadow node (the
6
+ * `style`), so the native side's per-size height is only a hint — without a
7
+ * JS-side height iOS bounds stay 0 and `onAdLoaded` never fires. The wrapper
8
+ * therefore applies one of these as a DEFAULT style; a consumer `style` wins.
9
+ */
10
+ const LAYOUT_SIZE: Record<string, { width: number; height: number }> = {
11
+ '320x50': { width: 320, height: 50 },
12
+ '320x100': { width: 320, height: 100 },
13
+ '320x130': { width: 320, height: 130 },
14
+ '300x250': { width: 300, height: 250 },
15
+ '320x480': { width: 320, height: 480 },
16
+ };
17
+
18
+ /** Resolve the default size for a layout; unknown/undefined → `300x250`. */
19
+ export function sizeForLayout(layout?: string) {
20
+ return LAYOUT_SIZE[layout ?? '300x250'] ?? LAYOUT_SIZE['300x250'];
21
+ }
package/src/types.ts ADDED
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Public, friendly types for the Buzzvil wrapper. These are the types
3
+ * consumers see; the native spec (`./NativeBuzzvil`) uses primitives only and
4
+ * the wrapper (`./buzzvil.native.tsx`) maps between the two.
5
+ */
6
+
7
+ /** Optional demographic hint used by Buzzvil for ad targeting. */
8
+ export type BuzzvilGender = 'MALE' | 'FEMALE';
9
+
10
+ /** A Buzzvil user. Only `userId` is required; the rest improve targeting. */
11
+ export interface BuzzvilUser {
12
+ /** Non-identifiable, persistent user id. ASCII, max 255 chars. */
13
+ userId: string;
14
+ gender?: BuzzvilGender;
15
+ /** 4-digit birth year, e.g. `1990`. */
16
+ birthYear?: number;
17
+ }
18
+
19
+ /** Options for presenting the BenefitHub (offerwall). */
20
+ export interface BenefitHubOptions {
21
+ /** BenefitHub page number from the Buzzvil admin (advanced routing). */
22
+ routePath?: string;
23
+ /** Open directly on the history/earnings page instead of the default hub. */
24
+ showHistory?: boolean;
25
+ }
26
+
27
+ /** Supported Native-ad layout sizes (width x height in dp). */
28
+ export type BuzzvilNativeAdLayout =
29
+ | '320x50'
30
+ | '320x100'
31
+ | '320x130'
32
+ | '300x250'
33
+ | '320x480';
34
+
35
+ /** Friendly props for the `BuzzvilNativeAdView` Fabric component. */
36
+ export interface BuzzvilNativeAdViewProps {
37
+ unitId: string;
38
+ layout?: BuzzvilNativeAdLayout;
39
+ style?: import('react-native').StyleProp<import('react-native').ViewStyle>;
40
+ onAdLoaded?: (e: { width: number; height: number }) => void;
41
+ onAdFailed?: (e: { code: string; message: string }) => void;
42
+ onAdClicked?: () => void;
43
+ onImpressed?: () => void;
44
+ onRewarded?: (e: { success: boolean }) => void;
45
+ }