apparent-expo 0.0.0-stage → 0.2.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/CHANGELOG.md +20 -0
- package/LICENSE +21 -0
- package/README.md +105 -2
- package/dist/index.d.ts +181 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +995 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation.d.ts +18 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +33 -0
- package/dist/navigation.js.map +1 -0
- package/dist/router.d.ts +4 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +24 -0
- package/dist/router.js.map +1 -0
- package/package.json +80 -4
- package/src/index.ts +970 -0
- package/src/navigation.ts +37 -0
- package/src/router.ts +25 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Changelog: apparent-expo
|
|
2
|
+
|
|
3
|
+
All notable changes to this SDK. Versions follow [Semantic Versioning](https://semver.org); every Apparent SDK
|
|
4
|
+
(Expo, Swift, Kotlin, Flutter) carries the same version number and sends the same wire format.
|
|
5
|
+
|
|
6
|
+
## Unreleased
|
|
7
|
+
|
|
8
|
+
## 0.2.0
|
|
9
|
+
|
|
10
|
+
First release on npm as `apparent-expo`.
|
|
11
|
+
|
|
12
|
+
- Saves every event before sending, never sends two batches at once, backs off on errors and retries later.
|
|
13
|
+
- Works in bare React Native: `expo-application`, `expo-localization`, `react-native-device-info` and `expo-router`
|
|
14
|
+
are optional and used when the app has them.
|
|
15
|
+
- Screens from expo-router (`apparent-expo/router`) or React Navigation (`apparent-expo/navigation`).
|
|
16
|
+
- One id per person: the first id is kept after login; a reset lets the next login back in.
|
|
17
|
+
- iOS phone model, simulator flag, Play install referrer as `install_source` on Android's first open.
|
|
18
|
+
- Deep links, tapped notifications (`push_opened`), `beforeSend`, consent before anything is stored.
|
|
19
|
+
- Wrong app id or key prints one warning in development builds; dropped events are counted.
|
|
20
|
+
- Published build: ES modules in `dist/` with types and source maps.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ahmed Ashour
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,106 @@
|
|
|
1
|
-
#
|
|
1
|
+
# apparent-expo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Event SDK for Expo and bare React Native apps that report to an Apparent dashboard. No native code.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
On npm as [`apparent-expo`](https://www.npmjs.com/package/apparent-expo). Docs: https://apparent.fyi/docs/sdk/expo
|
|
8
|
+
|
|
9
|
+
**Expo** (managed or prebuild):
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npx expo install apparent-expo @react-native-async-storage/async-storage expo-application expo-localization
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Bare React Native** (no Expo modules needed):
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npm install apparent-expo @react-native-async-storage/async-storage
|
|
19
|
+
npm install react-native-device-info # optional: app version + Play install referrer without passing them yourself
|
|
20
|
+
cd ios && pod install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Only `react-native` and `@react-native-async-storage/async-storage` are required. `expo-application`,
|
|
24
|
+
`expo-localization`, `react-native-device-info`, `expo-router` and `react` are optional: each one is used when the
|
|
25
|
+
app has it.
|
|
26
|
+
|
|
27
|
+
| Sent with each batch | Expo app | Bare React Native |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| App version + build | expo-application | `appVersion` / `appBuild` in `init`, else react-native-device-info, else none |
|
|
30
|
+
| Language + region | expo-localization | iOS Settings (the phone's languages), Android I18nManager, else Intl |
|
|
31
|
+
| Time zone | expo-localization | Intl |
|
|
32
|
+
| Play install referrer (Android) | expo-application | react-native-device-info |
|
|
33
|
+
|
|
34
|
+
Without a version, `app_updated` can't be noticed, so pass `appVersion` if you have neither module.
|
|
35
|
+
|
|
36
|
+
## Quick start: Expo
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { Apparent } from "apparent-expo";
|
|
40
|
+
|
|
41
|
+
Apparent.init({ apiUrl: "https://in.apparent.fyi", app: "<app id>", key: "<write key>", disabled: __DEV__ });
|
|
42
|
+
Apparent.track("paywall_view", { source: "onboarding" });
|
|
43
|
+
Apparent.setProperties({ language: "de", plan: "free" }); // added to every event
|
|
44
|
+
await Apparent.linkRevenueCat(Purchases); // purchases join to what people did
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Screens in an expo-router app (call once in the root layout):
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { useApparentScreens } from "apparent-expo/router";
|
|
51
|
+
useApparentScreens();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick start: bare React Native
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { Apparent } from "apparent-expo";
|
|
58
|
+
import { apparentScreens } from "apparent-expo/navigation";
|
|
59
|
+
import { NavigationContainer, useNavigationContainerRef } from "@react-navigation/native";
|
|
60
|
+
import { version } from "./package.json"; // or leave out appVersion when react-native-device-info is installed
|
|
61
|
+
|
|
62
|
+
Apparent.init({ apiUrl: "https://in.apparent.fyi", app: "<app id>", key: "<write key>", appVersion: version, disabled: __DEV__ });
|
|
63
|
+
|
|
64
|
+
export default function App() {
|
|
65
|
+
const ref = useNavigationContainerRef();
|
|
66
|
+
return <NavigationContainer ref={ref} {...apparentScreens(ref)}>{/* … */}</NavigationContainer>;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`apparentScreens` has no dependency on React Navigation; it names each screen after the focused route. If you already
|
|
71
|
+
have `onReady` / `onStateChange`, call `screens.track()` from yours. Any other navigator: `Apparent.screen("Settings")`.
|
|
72
|
+
|
|
73
|
+
## Everything else (both)
|
|
74
|
+
|
|
75
|
+
Errors caught by an error boundary: `Apparent.captureError(error)`. Crashes and unhandled
|
|
76
|
+
promise rejections are captured automatically (release builds).
|
|
77
|
+
|
|
78
|
+
Logout: `Apparent.reset()`. Consent: `Apparent.optOut()` / `Apparent.optIn()` (remembered).
|
|
79
|
+
|
|
80
|
+
## What it promises
|
|
81
|
+
|
|
82
|
+
- Every event is on the phone within a quarter second, and right away when the app goes to the background or crashes.
|
|
83
|
+
- One send at a time; a batch only leaves the saved queue when the server has it. The server ignores duplicates.
|
|
84
|
+
- 10-second time limit per request; retries wait longer each time (2 s up to 5 min) and honour `Retry-After`.
|
|
85
|
+
- Too-large batches are split; refused batches are dropped instead of retried forever.
|
|
86
|
+
- Each batch carries the phone's clock, so the server can correct phones set to the wrong time.
|
|
87
|
+
- Up to 1,000 events wait offline; events older than a week are dropped.
|
|
88
|
+
- At most 100 events per request: a long queue goes out in several batches, nothing is cut.
|
|
89
|
+
- Events tracked right after `init()`, before the saved state is read, still get the saved user and properties, and a
|
|
90
|
+
`reset()` in that moment sticks. You don't need to `await Apparent.ready()`.
|
|
91
|
+
- A wrong app id or key (the server answers 401): the batch is dropped, and in development (`__DEV__` or `debug: true`)
|
|
92
|
+
it prints once: `Apparent: app id or key is wrong — events are not being saved`.
|
|
93
|
+
- Simulators are marked as test phones even without `expo-device`: in the iOS Simulator (told by where the JS bundle
|
|
94
|
+
was loaded from) and Android emulators (the build fingerprint) the batch says `simulator: true`, so Apparent leaves
|
|
95
|
+
them out. Real phones send exactly what they did before. With `expo-device`, its `isDevice` decides, and iOS also
|
|
96
|
+
gets the model (`"iPhone15,2"`).
|
|
97
|
+
|
|
98
|
+
Automatic events: `first_open`, `app_open` (each visit, not background launches), `app_updated`,
|
|
99
|
+
`app_background` (with seconds in the app), `install_source` (Android, from the Play referrer), `screen_view`, `error`.
|
|
100
|
+
|
|
101
|
+
## How the optional modules load
|
|
102
|
+
|
|
103
|
+
The SDK calls `require("expo-application")` (and the others) inside `try` blocks. Metro treats such a require as an
|
|
104
|
+
optional dependency (`allowOptionalDependencies`, on by default in React Native's and Expo's Metro configs), so an app
|
|
105
|
+
without the package still bundles. Re.Pack / webpack only warn. Expo apps send exactly what 0.2.0 sent
|
|
106
|
+
(`test/compat.test.ts` checks the bytes).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
export declare const SDK_VERSION = "0.2.0";
|
|
2
|
+
type Value = string | number | boolean | null;
|
|
3
|
+
export type Props = Record<string, Value | undefined>;
|
|
4
|
+
/** Printed once in development builds when the server answers 401. */
|
|
5
|
+
export declare const WRONG_KEY_WARNING = "Apparent: app id or key is wrong \u2014 events are not being saved";
|
|
6
|
+
export type Storage = {
|
|
7
|
+
getItem(key: string): Promise<string | null>;
|
|
8
|
+
setItem(key: string, value: string): Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
export type ApparentConfig = {
|
|
11
|
+
apiUrl: string;
|
|
12
|
+
app: string;
|
|
13
|
+
key: string;
|
|
14
|
+
/** A stable id you already have (an install id, the RevenueCat app user id) so events and purchases join. */
|
|
15
|
+
getAnonymousId?: () => Promise<string | null | undefined>;
|
|
16
|
+
userId?: string | null;
|
|
17
|
+
debug?: boolean;
|
|
18
|
+
/** Nothing is stored or sent. Use it in development. */
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/** Minutes in the background before a visit ends. Default 30. */
|
|
21
|
+
sessionTimeoutMinutes?: number;
|
|
22
|
+
/** Report JavaScript errors and crashes. Default true. */
|
|
23
|
+
captureErrors?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The app's version ("1.4.0") and build ("42"). Only needed in bare React Native apps without expo-application or
|
|
26
|
+
* react-native-device-info; it is how app_updated is noticed. Given here, it wins over what the modules say.
|
|
27
|
+
*/
|
|
28
|
+
appVersion?: string;
|
|
29
|
+
appBuild?: string;
|
|
30
|
+
/** Advanced, mostly for tests. */
|
|
31
|
+
storage?: Storage;
|
|
32
|
+
flushIntervalMs?: number;
|
|
33
|
+
flushAt?: number;
|
|
34
|
+
maxQueue?: number;
|
|
35
|
+
requestTimeoutMs?: number;
|
|
36
|
+
retryBaseMs?: number;
|
|
37
|
+
/** Send deep_link_opened when a link opens the app. Default true. */
|
|
38
|
+
trackDeepLinks?: boolean;
|
|
39
|
+
/** Send push_opened when someone taps a notification (needs expo-notifications in the app). Default true. */
|
|
40
|
+
trackPushOpens?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Runs on every event (automatic ones too) before it is queued, after its properties are cleaned. Return the event,
|
|
43
|
+
* changed, or null to drop it. Use it to remove personal data or skip noisy events. If it throws, the event is kept.
|
|
44
|
+
*/
|
|
45
|
+
beforeSend?: (event: ApparentEvent) => ApparentEvent | null | undefined;
|
|
46
|
+
/** Collect nothing until optIn() is called (for apps that ask for consent first). Remembered across launches. */
|
|
47
|
+
optOutByDefault?: boolean;
|
|
48
|
+
};
|
|
49
|
+
/** An event as beforeSend sees it. */
|
|
50
|
+
export type ApparentEvent = {
|
|
51
|
+
name: string;
|
|
52
|
+
props?: Record<string, Value>;
|
|
53
|
+
time: number;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* A link that opened the app, safe to store: secrets in the query or fragment become "[redacted]", a user:password@
|
|
57
|
+
* is dropped, and the whole string is cut to 500 characters. Also returns the utm_ campaign fields when present.
|
|
58
|
+
*/
|
|
59
|
+
export declare function cleanDeepLink(raw: string): {
|
|
60
|
+
url: string;
|
|
61
|
+
utm_source?: string;
|
|
62
|
+
utm_medium?: string;
|
|
63
|
+
utm_campaign?: string;
|
|
64
|
+
};
|
|
65
|
+
/** "en_DE@rg=atzzzz" / "en-DE" → { tag: "en-DE", region: "AT" } (the rg= override is the region the phone is set to). */
|
|
66
|
+
export declare function parseLocale(raw: unknown): {
|
|
67
|
+
tag: string;
|
|
68
|
+
region: string | null;
|
|
69
|
+
} | null;
|
|
70
|
+
/**
|
|
71
|
+
* True in the iOS Simulator or an Android emulator, so Apparent leaves it out of the counts. expo-device's isDevice when
|
|
72
|
+
* the app has it; otherwise React Native's own: the bundle's path on iOS, the build fingerprint on Android.
|
|
73
|
+
*/
|
|
74
|
+
export declare function isSimulator(): boolean;
|
|
75
|
+
export declare class ApparentClient {
|
|
76
|
+
private cfg;
|
|
77
|
+
private storage;
|
|
78
|
+
private anon;
|
|
79
|
+
private anonSource;
|
|
80
|
+
private userId;
|
|
81
|
+
private props;
|
|
82
|
+
private optedOut;
|
|
83
|
+
private appVersion;
|
|
84
|
+
private queue;
|
|
85
|
+
private inflight;
|
|
86
|
+
private sessionId;
|
|
87
|
+
private device;
|
|
88
|
+
private loading;
|
|
89
|
+
/** The saved state has been read; until then nothing may be written over it. */
|
|
90
|
+
private loaded;
|
|
91
|
+
private sending;
|
|
92
|
+
private sendAgain;
|
|
93
|
+
private failures;
|
|
94
|
+
private retryAt;
|
|
95
|
+
/** How long the current wait was meant to be, to spot a clock that jumped back since. */
|
|
96
|
+
private retryWait;
|
|
97
|
+
private retryReason;
|
|
98
|
+
private batchSize;
|
|
99
|
+
private persistTimer;
|
|
100
|
+
private interval;
|
|
101
|
+
private appStateSub;
|
|
102
|
+
private appState;
|
|
103
|
+
private activeSince;
|
|
104
|
+
private backgroundAt;
|
|
105
|
+
private pendingOpen;
|
|
106
|
+
private screenName;
|
|
107
|
+
private errorsThisVisit;
|
|
108
|
+
/** Events tracked before the saved state was read (see restore). */
|
|
109
|
+
private early;
|
|
110
|
+
private resetBeforeLoad;
|
|
111
|
+
private identifiedBeforeLoad;
|
|
112
|
+
private warnedKey;
|
|
113
|
+
/** optIn() or optOut() before the saved state was read: that choice wins over the saved one. */
|
|
114
|
+
private consentBeforeLoad;
|
|
115
|
+
private consented;
|
|
116
|
+
private warnedHook;
|
|
117
|
+
private linkSub;
|
|
118
|
+
private pushSub;
|
|
119
|
+
private lastPush;
|
|
120
|
+
init(cfg: ApparentConfig): void;
|
|
121
|
+
private start;
|
|
122
|
+
/** deep_link_opened for the link the app was launched with, and for each link that brings it back to the front. */
|
|
123
|
+
private watchDeepLinks;
|
|
124
|
+
/** push_opened when a notification is tapped, with only the campaign and title the app put in its data. */
|
|
125
|
+
private watchPushOpens;
|
|
126
|
+
private restore;
|
|
127
|
+
/** Android only: the Play install referrer (what the store link carried, e.g. "utm_source=reddit&utm_campaign=launch"). iOS has none. */
|
|
128
|
+
private recordInstallSource;
|
|
129
|
+
private open;
|
|
130
|
+
private onAppState;
|
|
131
|
+
private enqueue;
|
|
132
|
+
/** The app's beforeSend: the event it returns (cleaned again), or null when it drops it. A hook that throws keeps it. */
|
|
133
|
+
private hook;
|
|
134
|
+
/** Record something a person did. Names: lowercase_snake. Props: flat values. */
|
|
135
|
+
track(name: string, props?: Props): void;
|
|
136
|
+
/** Record that a screen was shown. Repeats of the current screen are ignored. */
|
|
137
|
+
screen(name: string, props?: Props): void;
|
|
138
|
+
/** Report an error you caught yourself (an error boundary, a failed request). */
|
|
139
|
+
captureError(error: unknown, extra?: {
|
|
140
|
+
fatal?: boolean;
|
|
141
|
+
how?: string;
|
|
142
|
+
[key: string]: Value | undefined;
|
|
143
|
+
}): void;
|
|
144
|
+
/** Who is using the app, once they log in. `null` when they log out (or call reset()). */
|
|
145
|
+
identify(userId: string | null): void;
|
|
146
|
+
/** Properties added to every event from now on, e.g. { language: "de", plan: "pro" }. `null` removes one. */
|
|
147
|
+
setProperties(props: Props): void;
|
|
148
|
+
unsetProperty(key: string): void;
|
|
149
|
+
/** Someone logged out: forget who they were and start a new anonymous id. */
|
|
150
|
+
reset(): void;
|
|
151
|
+
/** Stop collecting (for example when someone declines analytics). Remembered across launches. */
|
|
152
|
+
optOut(): void;
|
|
153
|
+
/** Start collecting again, or for the first time with optOutByDefault. Remembered across launches. */
|
|
154
|
+
optIn(): void;
|
|
155
|
+
/** Resolves once saved events and ids are loaded (anonymousId is final from then on). */
|
|
156
|
+
ready(): Promise<void>;
|
|
157
|
+
get isOptedOut(): boolean;
|
|
158
|
+
get anonymousId(): string;
|
|
159
|
+
/** Store this person's Apparent id on their RevenueCat customer, so purchases join to what they did. */
|
|
160
|
+
linkRevenueCat(purchases: {
|
|
161
|
+
setAttributes(attributes: Record<string, string | null>): unknown;
|
|
162
|
+
}): Promise<void>;
|
|
163
|
+
/** Send what is queued now. Safe to call any time: only one send runs at once. */
|
|
164
|
+
flush(): Promise<void>;
|
|
165
|
+
private drain;
|
|
166
|
+
/** True once the retry wait is over. A wait that is now longer than it was set to means the phone's clock went back:
|
|
167
|
+
* it's over too, so a clock change never holds the queue (PostHog and Amplitude test the same). */
|
|
168
|
+
private due;
|
|
169
|
+
private send;
|
|
170
|
+
private schedulePersist;
|
|
171
|
+
private persistNow;
|
|
172
|
+
private installErrorHandlers;
|
|
173
|
+
/** Stop timers and listeners, after saving what is queued. For tests and hot reload. */
|
|
174
|
+
shutdown(): Promise<void>;
|
|
175
|
+
/** Public methods never throw into the app (SPEC 6). */
|
|
176
|
+
private guard;
|
|
177
|
+
private log;
|
|
178
|
+
}
|
|
179
|
+
export declare const Apparent: ApparentClient;
|
|
180
|
+
export default Apparent;
|
|
181
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|