Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,45 @@
# Changelog

## 0.1.1

Implements [wrapper parity 0.1.1](https://github.com/linktrail-io/workspace/blob/main/contracts/wrapper-parity-0.1.1.md).
Native SDKs unchanged: iOS `LinkTrailSDK ~> 0.1.0`, Android `io.linktrail:sdk:0.1.0`.

### Changed
- **Breaking: error codes are now camelCase**, matching the native `LinkTrailError` cases. Every
promise rejects with a `LinkTrailError` whose `message` is the native message unchanged; `server`
errors also carry `statusCode` and, if present, `body` (also on `onError` events). For this
release the old value is still available as `error.legacyCode`; it will be removed in the next
minor release.

| Before (`code`, now `legacyCode`) | After (`code`) |
| --- | --- |
| `missing_api_key` | `missingApiKey` |
| `invalid_api_key` | `invalidApiKey` |
| `not_configured` | `notConfigured` |
| `invalid_url` | `invalidUrl` |
| `not_a_linktrail_url` | `notALinkTrailUrl` |
| `empty_response` | `emptyResponse` |
| `invalid_argument` | `invalidArgument` |
| `transport`, `server`, `decoding`, `unknown` | unchanged |

- **Links and attribution are no longer lost before a listener exists.** The native `onLink` is
registered only when the first JS `onLink` listener subscribes, so a deferred link stays saved
natively until JS receives it. Re-engagement links resolved earlier are buffered (max 10, oldest
dropped) and delivered once, in order, to the first listener. `onAttribution` keeps the last
result and replays it to the first listener. Later listeners get no replays. `onLink` /
`onAttribution` now return a JS subscription (still `{ remove() }`).
- **Behavior change (Android):** `requestTrackingAuthorization()` now resolves `true` instead of
`false`. Android has no App Tracking Transparency, so the platform never restricts tracking;
this matches the Flutter SDK. It is not user consent — keep using `setConsent` /
`requireConsent`. iOS is unchanged.

### Added
- `LinkTrail.version` (this package's version) and `LinkTrail.nativeSdkVersion` (the embedded
native SDK's version).
- `LinkTrailError` class and `LinkTrailErrorCode` type exports.
- A Jest test suite (`npm test`) covering the JS/TS layer with a mocked native module.

## 0.1.0

Adopts the native **0.1.0** SDKs: iOS `LinkTrailSDK ~> 0.1.0` (from `0.0.11`) and Android
Expand Down
34 changes: 32 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ from Maven Central — so there's nothing else to add.
## Quick start

```ts
import LinkTrail from 'linktrail-react-native';
import LinkTrail, { LinkTrailError } from 'linktrail-react-native';

// At app launch. The API key is required.
await LinkTrail.configure('lt_live_…');
Expand All @@ -43,6 +43,30 @@ LinkTrail.onError((error) => console.warn(`[LinkTrail] ${error.code}: ${error.me
The install is tracked automatically by `configure`, and incoming links (Universal Links / App
Links / custom schemes) are forwarded via React Native's `Linking` API — no extra wiring.

`onLink` can be registered after a splash or login screen: links that arrive before the first
listener are kept and delivered to it once, in order (later listeners get no replays). A deferred
link stays saved natively (across launches) until a listener exists; up to 10 re-engagement links
are buffered in memory. `onAttribution` replays the latest result to its first listener.

### Errors

Every promise rejects with a `LinkTrailError`, and `onError` gets the same fields:

| Field | |
| --- | --- |
| `code` | `missingApiKey`, `invalidApiKey`, `notConfigured`, `invalidUrl`, `notALinkTrailUrl`, `transport`, `server`, `decoding`, `emptyResponse`, `invalidArgument`, `unknown` |
| `message` | The native SDK's message, unchanged |
| `statusCode`, `body` | `server` errors only (`body` when the server sent one) |
| `legacyCode` | The pre-0.1.1 snake_case code. Deprecated; removed in the next minor release |

```ts
try {
await LinkTrail.trackEvent('purchase');
} catch (e) {
if (e instanceof LinkTrailError && e.code === 'server') console.warn(e.statusCode, e.body);
}
```

## More

```ts
Expand All @@ -52,8 +76,14 @@ await LinkTrail.trackEvent('purchase', { value: 59.99, currency: 'USD' });
// Cached results:
const attribution = await LinkTrail.getLastAttribution();
const lastLink = await LinkTrail.getLastDeepLink();

// Versions: this package, and the embedded native SDK.
LinkTrail.version; // "0.1.1"
LinkTrail.nativeSdkVersion; // e.g. "0.1.0"

// iOS ATT / SKAdNetwork (no-ops on Android):
// iOS ATT / SKAdNetwork. On Android there is no ATT: requestTrackingAuthorization()
// is not applicable and resolves `true` (the OS does not restrict tracking); the
// SKAdNetwork calls are no-ops.
await LinkTrail.requestTrackingAuthorization();
LinkTrail.registerForSKAdAttribution();
LinkTrail.updateConversionValue(42, 'medium');
Expand Down
Loading
Loading