@simula/ads 1.1.0 → 1.3.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/README.md +51 -356
- package/dist/InChatAdSlot.d.ts.map +1 -1
- package/dist/components/GameCard.d.ts +11 -0
- package/dist/components/GameCard.d.ts.map +1 -0
- package/dist/components/GameGrid.d.ts +12 -0
- package/dist/components/GameGrid.d.ts.map +1 -0
- package/dist/components/GameIframe.d.ts +9 -0
- package/dist/components/GameIframe.d.ts.map +1 -0
- package/dist/components/MiniGameMenu.d.ts +4 -0
- package/dist/components/MiniGameMenu.d.ts.map +1 -0
- package/dist/components/inChatAd/InChatAdSlot.d.ts +4 -0
- package/dist/components/inChatAd/InChatAdSlot.d.ts.map +1 -0
- package/dist/components/miniGame/GameCard.d.ts +11 -0
- package/dist/components/miniGame/GameCard.d.ts.map +1 -0
- package/dist/components/miniGame/GameGrid.d.ts +12 -0
- package/dist/components/miniGame/GameGrid.d.ts.map +1 -0
- package/dist/components/miniGame/GameIframe.d.ts +9 -0
- package/dist/components/miniGame/GameIframe.d.ts.map +1 -0
- package/dist/components/miniGame/MiniGameMenu.d.ts +4 -0
- package/dist/components/miniGame/MiniGameMenu.d.ts.map +1 -0
- package/dist/components/miniGame/mockGames.d.ts +3 -0
- package/dist/components/miniGame/mockGames.d.ts.map +1 -0
- package/dist/components/mockGames.d.ts +3 -0
- package/dist/components/mockGames.d.ts.map +1 -0
- package/dist/components/sponsoredSuggestions/SponsoredSuggestions.d.ts +4 -0
- package/dist/components/sponsoredSuggestions/SponsoredSuggestions.d.ts.map +1 -0
- package/dist/index.d.ts +121 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2117 -248
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2070 -205
- package/dist/index.mjs.map +1 -1
- package/dist/types/SimulaProvider.d.ts +5 -0
- package/dist/types/SimulaProvider.d.ts.map +1 -0
- package/dist/types/components/inChatAd/InChatAdSlot.d.ts +4 -0
- package/dist/types/components/inChatAd/InChatAdSlot.d.ts.map +1 -0
- package/dist/types/components/miniGame/GameCard.d.ts +12 -0
- package/dist/types/components/miniGame/GameCard.d.ts.map +1 -0
- package/dist/types/components/miniGame/GameGrid.d.ts +13 -0
- package/dist/types/components/miniGame/GameGrid.d.ts.map +1 -0
- package/dist/types/components/miniGame/GameIframe.d.ts +21 -0
- package/dist/types/components/miniGame/GameIframe.d.ts.map +1 -0
- package/dist/types/components/miniGame/MiniGameMenu.d.ts +4 -0
- package/dist/types/components/miniGame/MiniGameMenu.d.ts.map +1 -0
- package/dist/types/components/miniGame/mockGames.d.ts +3 -0
- package/dist/types/components/miniGame/mockGames.d.ts.map +1 -0
- package/dist/types/components/nativeBanner/NativeBanner.d.ts +4 -0
- package/dist/types/components/nativeBanner/NativeBanner.d.ts.map +1 -0
- package/dist/types/components/nativeBanner/NativeBannerTest.d.ts +4 -0
- package/dist/types/components/nativeBanner/NativeBannerTest.d.ts.map +1 -0
- package/dist/types/components/nativeBanner/RadialLinesSpinner.d.ts +7 -0
- package/dist/types/components/nativeBanner/RadialLinesSpinner.d.ts.map +1 -0
- package/dist/types/components/nativeBanner/index.d.ts +3 -0
- package/dist/types/components/nativeBanner/index.d.ts.map +1 -0
- package/dist/types/components/sponsoredSuggestions/SponsoredSuggestions.d.ts +4 -0
- package/dist/types/components/sponsoredSuggestions/SponsoredSuggestions.d.ts.map +1 -0
- package/dist/types/hooks/useAssetLoadDetection.d.ts +14 -0
- package/dist/types/hooks/useAssetLoadDetection.d.ts.map +1 -0
- package/dist/types/hooks/useBotDetection.d.ts +3 -0
- package/dist/types/hooks/useBotDetection.d.ts.map +1 -0
- package/dist/types/hooks/useDebounce.d.ts +2 -0
- package/dist/types/hooks/useDebounce.d.ts.map +1 -0
- package/dist/types/hooks/useOMIDViewability.d.ts +24 -0
- package/dist/types/hooks/useOMIDViewability.d.ts.map +1 -0
- package/dist/types/hooks/useViewability.d.ts +6 -0
- package/dist/types/hooks/useViewability.d.ts.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types.d.ts +189 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils/api.d.ts +62 -0
- package/dist/types/utils/api.d.ts.map +1 -0
- package/dist/types/utils/colorThemes.d.ts +21 -0
- package/dist/types/utils/colorThemes.d.ts.map +1 -0
- package/dist/types/utils/styling.d.ts +4 -0
- package/dist/types/utils/styling.d.ts.map +1 -0
- package/dist/types/utils/validation.d.ts +27 -0
- package/dist/types/utils/validation.d.ts.map +1 -0
- package/dist/types.d.ts +51 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/api.d.ts +2 -3
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/styling.d.ts +4 -3
- package/dist/utils/styling.d.ts.map +1 -1
- package/dist/utils/validation.d.ts +2 -7
- package/dist/utils/validation.d.ts.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
# Simula Ad SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Overview
|
|
4
4
|
|
|
5
|
-
Simula
|
|
5
|
+
The Simula Ad SDK enables React developers to monetize conversational AI applications with contextually relevant, non-intrusive ads. The SDK provides in-chat ad placements and native banner ads that integrate naturally with chat interfaces.
|
|
6
|
+
|
|
7
|
+
### Key Features
|
|
8
|
+
|
|
9
|
+
- **Contextual Targeting** - AI-powered ad matching based on conversation content
|
|
10
|
+
- **In-Chat Ad Slots** - Ad placements that blend seamlessly into chat UIs
|
|
11
|
+
- **Native Banner Ads** - Flexible ad placements for feeds and content surfaces
|
|
12
|
+
- **MRC-Compliant Viewability** - Industry-standard impression tracking
|
|
13
|
+
- **Built-in A/B Testing** - Optimize ad performance automatically
|
|
6
14
|
|
|
7
15
|
---
|
|
8
16
|
|
|
9
|
-
##
|
|
17
|
+
## Installation
|
|
10
18
|
|
|
11
19
|
```bash
|
|
12
20
|
npm install @simula/ads
|
|
@@ -14,393 +22,80 @@ npm install @simula/ads
|
|
|
14
22
|
|
|
15
23
|
---
|
|
16
24
|
|
|
17
|
-
##
|
|
25
|
+
## Quick Start
|
|
18
26
|
|
|
19
|
-
|
|
27
|
+
### 1. Provider Setup
|
|
20
28
|
|
|
21
|
-
|
|
22
|
-
2. **Insert** `<InChatAdSlot />` where you want ads
|
|
29
|
+
Wrap your chat/conversation component with `SimulaProvider` to initialize the SDK:
|
|
23
30
|
|
|
24
31
|
```tsx
|
|
25
|
-
import { SimulaProvider
|
|
26
|
-
|
|
27
|
-
function App() {
|
|
28
|
-
return (
|
|
29
|
-
<div>
|
|
30
|
-
<Header />
|
|
31
|
-
<ChatInterface /> {/* SimulaProvider wraps individual conversations */}
|
|
32
|
-
</div>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
32
|
+
import { SimulaProvider } from "@simula/ads";
|
|
35
33
|
|
|
36
34
|
function ChatInterface() {
|
|
37
|
-
const [messages, setMessages] = useState([]);
|
|
38
|
-
|
|
39
35
|
return (
|
|
40
|
-
<SimulaProvider
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<InChatAdSlot
|
|
47
|
-
messages={messages.slice(0, i + 1)}
|
|
48
|
-
formats="all"
|
|
49
|
-
theme={{ theme: "light", accent: "blue" }}
|
|
50
|
-
/>
|
|
51
|
-
)}
|
|
52
|
-
</div>
|
|
53
|
-
))}
|
|
54
|
-
</div>
|
|
55
|
-
</SimulaProvider>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## 🧩 Components
|
|
63
|
-
|
|
64
|
-
### `SimulaProvider`
|
|
65
|
-
|
|
66
|
-
Initializes the SDK and manages session state.
|
|
67
|
-
|
|
68
|
-
| Prop | Type | Required | Default | Description |
|
|
69
|
-
| --------------- | ----------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
70
|
-
| `apiKey` | `string` | ✅ | — | Your Simula API key from the [dashboard](https://simula.ad) |
|
|
71
|
-
| `children` | `ReactNode` | ✅ | — | Your app components |
|
|
72
|
-
| `devMode` | `boolean` | ❌ | `false` | Enables development mode |
|
|
73
|
-
| `primaryUserID` | `string` | ❌ | — | Publisher-provided user identifier. **Recommended** for consistent tracking across devices and sessions. |
|
|
74
|
-
|
|
75
|
-
```tsx
|
|
76
|
-
// Wrap individual chat/conversation components
|
|
77
|
-
function ChatInterface({ conversationId }) {
|
|
78
|
-
const [messages, setMessages] = useState([]);
|
|
79
|
-
|
|
80
|
-
return (
|
|
81
|
-
<SimulaProvider apiKey="SIMULA_xxx">
|
|
82
|
-
{/* Your chat UI */}
|
|
83
|
-
</SimulaProvider>
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// For authenticated apps with user tracking (recommended)
|
|
88
|
-
function ChatInterface({ conversationId, userId }) {
|
|
89
|
-
const [messages, setMessages] = useState([]);
|
|
90
|
-
|
|
91
|
-
return (
|
|
92
|
-
<SimulaProvider apiKey="SIMULA_xxx" primaryUserID={userId}>
|
|
36
|
+
<SimulaProvider
|
|
37
|
+
apiKey="SIMULA_xxx"
|
|
38
|
+
primaryUserID="user-123" // Optional: User ID for better ad targeting
|
|
39
|
+
hasPrivacyConsent={true} // Optional: Privacy consent flag
|
|
40
|
+
devMode={false} // Optional: Enable dev mode for testing
|
|
41
|
+
>
|
|
93
42
|
{/* Your chat UI */}
|
|
94
43
|
</SimulaProvider>
|
|
95
44
|
);
|
|
96
45
|
}
|
|
97
46
|
```
|
|
98
47
|
|
|
99
|
-
|
|
100
|
-
>
|
|
101
|
-
> * **Wrap individual conversations** – Place `SimulaProvider` around each chat or character component so that each conversation is treated as a separate session. This provides better ad targeting based on conversation context.
|
|
102
|
-
>
|
|
103
|
-
> * **Provide `primaryUserID`** – Use your user's ID to enable cross-device tracking and cookie-independent identification. This approach delivers:
|
|
104
|
-
> * **Higher CPMs** – Better user attribution leads to more valuable ad placements
|
|
105
|
-
> * **Frequency capping** – Prevents oversending ads to the same user
|
|
106
|
-
> * **Better ad experience** – Optimized targeting based on consistent user history
|
|
107
|
-
> * **Accurate analytics** – Reliable performance metrics across devices and sessions
|
|
108
|
-
>
|
|
109
|
-
> * **One provider per conversation** – Don't nest multiple `SimulaProvider` instances. Each conversation/chat component should have its own provider at the top level.
|
|
110
|
-
>
|
|
111
|
-
> For anonymous users, you can still use `SimulaProvider` without `primaryUserID`, but tracking will rely on cookies.
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
### `InChatAdSlot`
|
|
116
|
-
|
|
117
|
-
Displays an ad based on conversation context.
|
|
118
|
-
|
|
119
|
-
| Prop | Type | Required | Default | Description |
|
|
120
|
-
| -------------- | ---------------------- | -------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
121
|
-
| `messages` | `Message[]` | ✅ | — | Array of `{ role, content }`; pass recent conversation (e.g. last 6 turns). |
|
|
122
|
-
| `trigger` | `Promise<any>` | ❌ | Fires immediately on viewability | Promise to await before fetching the ad (e.g. LLM call). |
|
|
123
|
-
| `formats` | `string \| string[]` | ❌ | `['all']` | Preferred ad formats: `'all'`, `'tips'`, `'interactive'`, `'suggestions'`, `'text'`, `'highlight'`, `'visual_banner'`, `'image_feature'`, or an array like `['text', 'highlight']`. See [Appendix: Ad Formats](#appendix-ad-formats) for visual examples.<br>**A/B Testing:** Pass an array to automatically A/B test different formats and let Simula pick the best over time. |
|
|
124
|
-
| `theme` | `SimulaTheme` | ❌ | `{ theme: 'auto', width: 'auto', accent: ['neutral','image'], font: 'sans-serif', cornerRadius: 8 }` | Customize ad appearance (see Theme Options). Arrays trigger A/B testing. |
|
|
125
|
-
| `charDesc` | `string` | ❌ | `undefined` | Character description for additional context to improve ad targeting. |
|
|
126
|
-
| `debounceMs` | `number` | ❌ | `0` | Delay in milliseconds before fetching. |
|
|
127
|
-
| `onImpression` | `(ad: AdData) => void` | ❌ | `undefined` | Callback when ad is viewable (50% visible for ≥1s). |
|
|
128
|
-
| `onClick` | `(ad: AdData) => void` | ❌ | `undefined` | Callback when ad is clicked. |
|
|
129
|
-
| `onError` | `(err: Error) => void` | ❌ | `undefined` | Callback when ad fails or no-fill occurs. |
|
|
130
|
-
|
|
131
|
-
**Behavior:**
|
|
132
|
-
|
|
133
|
-
* Fetches **once** per slot (static)
|
|
134
|
-
* Triggers on **viewport visibility** (50% visible)
|
|
135
|
-
* Includes built-in **bot protection**
|
|
136
|
-
* Tracks impressions **MRC-compliantly**
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
## 🎨 Theme Options
|
|
141
|
-
|
|
142
|
-
```ts
|
|
143
|
-
interface SimulaTheme {
|
|
144
|
-
theme?: "light" | "dark" | "auto"; // default: "auto"
|
|
145
|
-
accent?: AccentOption | AccentOption[]; // default: ["neutral", "image"] (A/B tested)
|
|
146
|
-
font?: FontOption | FontOption[]; // default: "sans-serif"
|
|
147
|
-
width?: number | string; // default: "auto" (min 320px)
|
|
148
|
-
cornerRadius?: number; // default: 8
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
**Modes:** `light` | `dark` | `auto`
|
|
153
|
-
**Accents:**
|
|
154
|
-
`blue`, `red`, `green`, `yellow`, `purple`, `pink`, `orange`, `neutral`, `gray`, `tan`, `transparent`, `image`
|
|
155
|
-
**Fonts:** `sans-serif`, `serif`, `monospace`
|
|
156
|
-
|
|
157
|
-
> **Height:** fixed at **265px**
|
|
158
|
-
> **Width:** min **320px**, accepts px/%, or `auto`
|
|
159
|
-
|
|
160
|
-
> **A/B Testing:**
|
|
161
|
-
> When you pass an **array** (e.g., `accent: ['blue', 'green', 'purple']`), Simula will **automatically A/B test** across the provided options—colors, fonts, or formats—and **optimize over time for the best-performing variant**.
|
|
162
|
-
|
|
163
|
-
```tsx
|
|
164
|
-
// Default theme (auto)
|
|
165
|
-
<InChatAdSlot messages={messages} />
|
|
166
|
-
|
|
167
|
-
// Light theme
|
|
168
|
-
<InChatAdSlot messages={messages} theme={{ theme: "light", accent: "blue" }} />
|
|
169
|
-
|
|
170
|
-
// Dark theme with custom width
|
|
171
|
-
<InChatAdSlot
|
|
172
|
-
messages={messages}
|
|
173
|
-
theme={{ theme: "dark", accent: "purple", width: 600, cornerRadius: 12 }}
|
|
174
|
-
/>
|
|
175
|
-
|
|
176
|
-
// A/B testing
|
|
177
|
-
<InChatAdSlot
|
|
178
|
-
messages={messages}
|
|
179
|
-
theme={{
|
|
180
|
-
accent: ["blue", "green", "purple"], // A/B test colors
|
|
181
|
-
font: ["sans-serif", "serif"], // A/B test fonts
|
|
182
|
-
width: "100%"
|
|
183
|
-
}}
|
|
184
|
-
/>
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## 💬 Integration Example
|
|
48
|
+
### 2. Component Integration
|
|
190
49
|
|
|
191
|
-
|
|
50
|
+
Add components where you want ads to appear:
|
|
192
51
|
|
|
52
|
+
**In-Chat Ads:**
|
|
193
53
|
```tsx
|
|
194
|
-
import {
|
|
195
|
-
import { SimulaProvider, InChatAdSlot } from "@simula/ads";
|
|
196
|
-
import OpenAI from "openai";
|
|
54
|
+
import { InChatAdSlot } from "@simula/ads";
|
|
197
55
|
|
|
198
|
-
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
199
|
-
|
|
200
|
-
export default function App() {
|
|
201
|
-
return (
|
|
202
|
-
<div>
|
|
203
|
-
<Header />
|
|
204
|
-
<ChatApp /> {/* Each conversation has its own SimulaProvider */}
|
|
205
|
-
</div>
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
function ChatApp() {
|
|
210
|
-
const [messages, setMessages] = useState([]);
|
|
211
|
-
const [input, setInput] = useState("");
|
|
212
|
-
const [loading, setLoading] = useState(false);
|
|
213
|
-
|
|
214
|
-
async function sendMessage() {
|
|
215
|
-
if (!input.trim()) return;
|
|
216
|
-
|
|
217
|
-
const userMessage = { role: "user", content: input.trim() };
|
|
218
|
-
const newMessages = [...messages, userMessage];
|
|
219
|
-
setMessages(newMessages);
|
|
220
|
-
setInput("");
|
|
221
|
-
setLoading(true);
|
|
222
|
-
|
|
223
|
-
try {
|
|
224
|
-
const llmPromise = client.chat.completions.create({
|
|
225
|
-
model: "gpt-4o-mini",
|
|
226
|
-
messages: newMessages,
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
const res = await llmPromise;
|
|
230
|
-
const reply = res.choices[0].message;
|
|
231
|
-
|
|
232
|
-
setMessages((prev) => [...prev, { ...reply, llmPromise }]);
|
|
233
|
-
} finally {
|
|
234
|
-
setLoading(false);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
return (
|
|
239
|
-
<SimulaProvider apiKey="SIMULA_xxx">
|
|
240
|
-
<div className="chat">
|
|
241
|
-
{messages.map((msg, i) => (
|
|
242
|
-
<div key={i}>
|
|
243
|
-
<p><strong>{msg.role}:</strong> {msg.content}</p>
|
|
244
|
-
|
|
245
|
-
{msg.role === "assistant" && (
|
|
246
|
-
<InChatAdSlot
|
|
247
|
-
key={`adslot-${i}`} // ✅ Required if rendering in a list
|
|
248
|
-
trigger={msg.llmPromise} // default: fires immediately if not provided
|
|
249
|
-
messages={messages.slice(0, i + 1)}
|
|
250
|
-
formats="all"
|
|
251
|
-
theme={{ theme: "light", accent: "blue", width: "auto" }}
|
|
252
|
-
/>
|
|
253
|
-
)}
|
|
254
|
-
</div>
|
|
255
|
-
))}
|
|
256
|
-
|
|
257
|
-
<input
|
|
258
|
-
value={input}
|
|
259
|
-
onChange={(e) => setInput(e.target.value)}
|
|
260
|
-
onKeyDown={(e) => e.key === "Enter" && sendMessage()}
|
|
261
|
-
/>
|
|
262
|
-
<button onClick={sendMessage} disabled={loading}>Send</button>
|
|
263
|
-
</div>
|
|
264
|
-
</SimulaProvider>
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
> **Tips:**
|
|
270
|
-
>
|
|
271
|
-
> * **Wrap `SimulaProvider` around the chat component** – This treats each conversation as a separate session for better ad targeting.
|
|
272
|
-
> * Use `key` prop when `<InChatAdSlot />` is rendered inside a list or dynamic loop.
|
|
273
|
-
> * The `trigger` prop waits for the LLM response before fetching ads. If omitted, the ad fetches immediately when viewable.
|
|
274
|
-
|
|
275
|
-
---
|
|
276
|
-
|
|
277
|
-
## 🔑 Features
|
|
278
|
-
|
|
279
|
-
* **Contextual Targeting** – AI-powered ad matching to conversation content
|
|
280
|
-
* **Bot Protection** – via [@fingerprintjs/botd](https://github.com/fingerprintjs/botd)
|
|
281
|
-
* **MRC-Compliant Viewability** – 50% visible for ≥1s
|
|
282
|
-
* **Responsive** – Flexible widths with enforced minimums
|
|
283
|
-
* **Static Fetch** – Each slot fetches once and stays fixed
|
|
284
|
-
* **Session Management** – Automatic
|
|
285
|
-
* **Robust Error Handling** – Graceful degradation & callbacks
|
|
286
|
-
* **TypeScript Support** – Built-in type definitions
|
|
287
|
-
* **Built-in A/B Testing** – Test multiple colors, formats, or fonts by passing arrays and let Simula optimize performance over time
|
|
288
|
-
|
|
289
|
-
---
|
|
290
|
-
|
|
291
|
-
## ⚙️ Advanced Usage
|
|
292
|
-
|
|
293
|
-
### Event Handlers
|
|
294
|
-
|
|
295
|
-
```tsx
|
|
296
56
|
<InChatAdSlot
|
|
297
|
-
messages={messages}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
onError={(err) => console.error("Ad error:", err)}
|
|
57
|
+
messages={messages.slice(0, i + 1)}
|
|
58
|
+
theme={{ mode: "light", accent: "blue" }}
|
|
59
|
+
onImpression={(ad) => console.log("Impression:", ad.id)}
|
|
60
|
+
onError={(err) => console.error("Ad error:", err)}
|
|
301
61
|
/>
|
|
302
62
|
```
|
|
303
63
|
|
|
304
|
-
|
|
305
|
-
|
|
64
|
+
**Native Banner Ads:**
|
|
306
65
|
```tsx
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
66
|
+
import { NativeBanner } from "@simula/ads";
|
|
67
|
+
|
|
68
|
+
<NativeBanner
|
|
69
|
+
slot="feed"
|
|
70
|
+
position={index}
|
|
71
|
+
context={{
|
|
72
|
+
searchTerm: "cooking recipes",
|
|
73
|
+
tags: ["food", "cooking"],
|
|
74
|
+
}}
|
|
75
|
+
width="100%"
|
|
76
|
+
onImpression={(ad) => console.log("Impression:", ad.id)}
|
|
77
|
+
onError={(err) => console.error("Error:", err)}
|
|
310
78
|
/>
|
|
311
79
|
```
|
|
312
80
|
|
|
313
81
|
---
|
|
314
82
|
|
|
315
|
-
##
|
|
316
|
-
|
|
317
|
-
```ts
|
|
318
|
-
import type {
|
|
319
|
-
SimulaTheme,
|
|
320
|
-
Message,
|
|
321
|
-
AdData,
|
|
322
|
-
InChatAdSlotProps,
|
|
323
|
-
SimulaProviderProps
|
|
324
|
-
} from "@simula/ads";
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
---
|
|
83
|
+
## Documentation
|
|
328
84
|
|
|
329
|
-
|
|
85
|
+
For complete API reference, integration guides, and examples:
|
|
330
86
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
* Support: **[admin@simula.ad](mailto:admin@simula.ad)**
|
|
87
|
+
- **[InChatAdSlot Documentation](https://simula-ad.notion.site/?pvs=73)**
|
|
88
|
+
- **[NativeBanner Documentation](https://simula-ad.notion.site/Komiko-Simula-Integration-2cbaf70f6f0d80338ddcd2efbbe5d3d7?source=copy_link)**
|
|
334
89
|
|
|
335
90
|
---
|
|
336
91
|
|
|
337
|
-
##
|
|
92
|
+
## Support
|
|
338
93
|
|
|
339
|
-
|
|
94
|
+
- **Website:** [simula.ad](https://simula.ad)
|
|
95
|
+
- **Email:** [admin@simula.ad](mailto:admin@simula.ad)
|
|
340
96
|
|
|
341
97
|
---
|
|
342
98
|
|
|
343
|
-
##
|
|
344
|
-
|
|
345
|
-
Visual examples of all available ad formats across mobile and desktop:
|
|
346
|
-
|
|
347
|
-
| Format | Mobile | Desktop |
|
|
348
|
-
|--------|--------|---------|
|
|
349
|
-
| **tips** | <img src="./assets/tips_mobile.png" width="200" alt="Tips format on mobile" /> | <img src="./assets/tips_desktop.png" width="400" alt="Tips format on desktop" /> |
|
|
350
|
-
| **interactive** | <img src="./assets/interactive_mobile.png" width="200" alt="Interactive format on mobile" /> | <img src="./assets/interactive_desktop.png" width="400" alt="Interactive format on desktop" /> |
|
|
351
|
-
| **suggestions** | <img src="./assets/suggestions_mobile.png" width="200" alt="Suggestions format on mobile" /> | <img src="./assets/suggestions_desktop.png" width="400" alt="Suggestions format on desktop" /> |
|
|
352
|
-
| **text** | <img src="./assets/text_mobile.png" width="200" alt="Text format on mobile" /> | <img src="./assets/text_desktop.png" width="400" alt="Text format on desktop" /> |
|
|
353
|
-
| **highlight** | <img src="./assets/highlight_mobile.png" width="200" alt="Highlight format on mobile" /> | <img src="./assets/highlight_desktop.png" width="400" alt="Highlight format on desktop" /> |
|
|
354
|
-
| **visual_banner** | <img src="./assets/visual_banner_mobile.png" width="200" alt="Visual banner format on mobile" /> | <img src="./assets/visual_banner_desktop.png" width="400" alt="Visual banner format on desktop" /> |
|
|
355
|
-
| **image_feature** | <img src="./assets/image_feature_mobile.png" width="200" alt="Image feature format on mobile" /> | <img src="./assets/image_feature_desktop.png" width="400" alt="Image feature format on desktop" /> |
|
|
356
|
-
|
|
357
|
-
> **Note:** The `'all'` format allows Simula to automatically select the best format based on context and performance.
|
|
358
|
-
|
|
359
|
-
---
|
|
360
|
-
|
|
361
|
-
## 📑 Appendix: Invalid Format & Accent Combinations
|
|
362
|
-
|
|
363
|
-
Certain ad formats have restrictions on which accent colors can be used. **These restrictions only apply when you specify an invalid combination with no other valid options.** When A/B testing with arrays, Simula automatically selects valid combinations from the available options.
|
|
99
|
+
## License
|
|
364
100
|
|
|
365
|
-
|
|
366
|
-
|--------|----------------|--------------|
|
|
367
|
-
| **interactive** | All colors, `'image'`, `'neutral'`, `'gray'`, `'tan'` | ❌ Cannot use `'transparent'` |
|
|
368
|
-
| **tips** | All colors, `'image'`, `'neutral'`, `'gray'`, `'tan'` | ❌ Cannot use `'transparent'` |
|
|
369
|
-
| **text** | **Only** `'transparent'` | ❌ Cannot use colors or `'image'` |
|
|
370
|
-
| **highlight** | All colors, `'image'`, `'neutral'`, `'gray'`, `'tan'` | ❌ Cannot use `'transparent'` |
|
|
371
|
-
| **visual_banner** | All colors, `'neutral'`, `'gray'`, `'tan'` | ❌ Cannot use `'image'` or `'transparent'` |
|
|
372
|
-
| **image_feature** | All colors, `'neutral'`, `'gray'`, `'tan'` | ❌ Cannot use `'image'` or `'transparent'` |
|
|
373
|
-
| **suggestions** | All accents allowed | ✅ No restrictions |
|
|
374
|
-
|
|
375
|
-
**Color accents:** `'blue'`, `'red'`, `'green'`, `'yellow'`, `'purple'`, `'pink'`, `'orange'`, `'neutral'`, `'gray'`, `'tan'`
|
|
376
|
-
|
|
377
|
-
### Examples
|
|
378
|
-
|
|
379
|
-
```tsx
|
|
380
|
-
// ✅ Valid - single format, single accent
|
|
381
|
-
<InChatAdSlot formats="interactive" theme={{ accent: "blue" }} />
|
|
382
|
-
<InChatAdSlot formats="text" theme={{ accent: "transparent" }} />
|
|
383
|
-
<InChatAdSlot formats="visual_banner" theme={{ accent: "purple" }} />
|
|
384
|
-
|
|
385
|
-
// ✅ Valid - A/B testing with arrays (Simula auto-selects valid combinations)
|
|
386
|
-
<InChatAdSlot
|
|
387
|
-
formats={['text', 'highlight']}
|
|
388
|
-
theme={{ accent: ['image', 'transparent'] }}
|
|
389
|
-
/>
|
|
390
|
-
// If 'text' is selected → uses 'transparent' (skips 'image')
|
|
391
|
-
// If 'highlight' is selected → uses 'image' (skips 'transparent')
|
|
392
|
-
|
|
393
|
-
<InChatAdSlot
|
|
394
|
-
formats={['interactive', 'visual_banner']}
|
|
395
|
-
theme={{ accent: ['blue', 'transparent'] }}
|
|
396
|
-
/>
|
|
397
|
-
// If 'interactive' is selected → uses 'blue' (skips 'transparent')
|
|
398
|
-
// If 'visual_banner' is selected → uses 'blue' (skips 'transparent')
|
|
399
|
-
|
|
400
|
-
// ❌ Invalid - no valid options available
|
|
401
|
-
<InChatAdSlot formats="interactive" theme={{ accent: "transparent" }} /> // interactive cannot use transparent (no fallback)
|
|
402
|
-
<InChatAdSlot formats="text" theme={{ accent: "blue" }} /> // text can ONLY use transparent (no fallback)
|
|
403
|
-
<InChatAdSlot formats="text" theme={{ accent: ['blue', 'red', 'image'] }} /> // text needs transparent but none provided
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
> **Key Point:** Restrictions only matter when there are **no valid alternatives**. When A/B testing with multiple formats or accents, Simula intelligently matches compatible combinations.
|
|
101
|
+
MIT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InChatAdSlot.d.ts","sourceRoot":"","sources":["../src/InChatAdSlot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AASjF,OAAO,EAAE,iBAAiB,EAAU,MAAM,SAAS,CAAC;AAepD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"InChatAdSlot.d.ts","sourceRoot":"","sources":["../src/InChatAdSlot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AASjF,OAAO,EAAE,iBAAiB,EAAU,MAAM,SAAS,CAAC;AAepD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqXpD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { GameData, MiniGameTheme } from '../types';
|
|
3
|
+
interface GameCardProps {
|
|
4
|
+
game: GameData;
|
|
5
|
+
charID: string;
|
|
6
|
+
theme: MiniGameTheme;
|
|
7
|
+
onGameSelect: (gameId: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare const GameCard: React.FC<GameCardProps>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=GameCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameCard.d.ts","sourceRoot":"","sources":["../../src/components/GameCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEnD,UAAU,aAAa;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA+N5C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { GameData, MiniGameTheme } from '../types';
|
|
3
|
+
interface GameGridProps {
|
|
4
|
+
games: GameData[];
|
|
5
|
+
maxGamesToShow: 3 | 6 | 9;
|
|
6
|
+
charID: string;
|
|
7
|
+
theme: MiniGameTheme;
|
|
8
|
+
onGameSelect: (gameId: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const GameGrid: React.FC<GameGridProps>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=GameGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameGrid.d.ts","sourceRoot":"","sources":["../../src/components/GameGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGnD,UAAU,aAAa;IACrB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,cAAc,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA0K5C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameIframe.d.ts","sourceRoot":"","sources":["../../src/components/GameIframe.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAGjD,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAsHhD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MiniGameMenu.d.ts","sourceRoot":"","sources":["../../src/components/MiniGameMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAiB,MAAM,UAAU,CAAC;AAc5D,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqVpD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InChatAdSlot.d.ts","sourceRoot":"","sources":["../../../src/components/inChatAd/InChatAdSlot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AASjF,OAAO,EAAE,iBAAiB,EAAU,MAAM,aAAa,CAAC;AAexD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqXpD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { GameData, MiniGameTheme } from '../../types';
|
|
3
|
+
interface GameCardProps {
|
|
4
|
+
game: GameData;
|
|
5
|
+
charID: string;
|
|
6
|
+
theme: MiniGameTheme;
|
|
7
|
+
onGameSelect: (gameId: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare const GameCard: React.FC<GameCardProps>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=GameCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameCard.d.ts","sourceRoot":"","sources":["../../../src/components/miniGame/GameCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEtD,UAAU,aAAa;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA+N5C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { GameData, MiniGameTheme } from '../../types';
|
|
3
|
+
interface GameGridProps {
|
|
4
|
+
games: GameData[];
|
|
5
|
+
maxGamesToShow: 3 | 6 | 9;
|
|
6
|
+
charID: string;
|
|
7
|
+
theme: MiniGameTheme;
|
|
8
|
+
onGameSelect: (gameId: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const GameGrid: React.FC<GameGridProps>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=GameGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameGrid.d.ts","sourceRoot":"","sources":["../../../src/components/miniGame/GameGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGtD,UAAU,aAAa;IACrB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,cAAc,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA0K5C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameIframe.d.ts","sourceRoot":"","sources":["../../../src/components/miniGame/GameIframe.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAGjD,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAsHhD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MiniGameMenu.d.ts","sourceRoot":"","sources":["../../../src/components/miniGame/MiniGameMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAiB,MAAM,aAAa,CAAC;AAc/D,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqVpD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockGames.d.ts","sourceRoot":"","sources":["../../../src/components/miniGame/mockGames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,eAAO,MAAM,SAAS,EAAE,QAAQ,EAuD/B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockGames.d.ts","sourceRoot":"","sources":["../../src/components/mockGames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,eAAO,MAAM,SAAS,EAAE,QAAQ,EAuD/B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SponsoredSuggestions.d.ts","sourceRoot":"","sources":["../../../src/components/sponsoredSuggestions/SponsoredSuggestions.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAA2B,MAAM,aAAa,CAAC;AAYjF,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAkJpE,CAAC"}
|