@tolinku/web-sdk 0.2.0 → 0.4.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 CHANGED
@@ -121,12 +121,17 @@ if (link) {
121
121
  console.log(link.deep_link_path); // e.g. "/merchant/xyz"
122
122
  }
123
123
 
124
- // Claim by device signal matching
124
+ // Claim by device signal matching. Timezone, language, screen size and pixel ratio
125
+ // are detected for you.
125
126
  const link = await tolinku.deferred.claimBySignals({
126
- appspaceId: 'your_appspace_id',
127
+ appspaceId: '64f0a1b2c3d4e5f60718',
127
128
  });
128
129
  ```
129
130
 
131
+ `appspaceId` is your Appspace ID, not your subdomain or slug. Copy it from the dashboard
132
+ under **Integrate** or **Settings**. It looks like `64f0a1b2c3d4e5f60718`.
133
+
134
+
130
135
  ### In-App Messages
131
136
 
132
137
  Display visually rich, server-configured messages as modal overlays. Create and manage messages from the Tolinku dashboard without shipping app updates.
package/dist/index.d.mts CHANGED
@@ -98,6 +98,8 @@ interface ClaimBySignalsOptions {
98
98
  language?: string;
99
99
  screenWidth?: number;
100
100
  screenHeight?: number;
101
+ /** Defaults to `window.devicePixelRatio`. Override only if you report a custom screen size. */
102
+ devicePixelRatio?: number;
101
103
  }
102
104
  /** Banner config returned by the API */
103
105
  interface BannerConfig {
@@ -118,13 +120,47 @@ interface BannerItem {
118
120
  text_color: string;
119
121
  cta_text: string | null;
120
122
  position: string | null;
123
+ style: string | null;
124
+ shadow: string | null;
125
+ radius: number | null;
126
+ margin: number | null;
121
127
  dismiss_days: number | null;
122
128
  priority: number;
123
129
  }
124
- /** Options for showing a banner */
130
+ /** Options for showing a banner. All fields are optional.
131
+ * Resolution chain per value: option → server config → theme → built-in default. */
125
132
  interface ShowBannerOptions {
126
133
  position?: 'top' | 'bottom';
134
+ style?: 'pinned' | 'floating' | 'stacked';
135
+ animation?: 'slide' | 'fade' | 'pop' | 'none';
136
+ theme?: 'light' | 'dark';
127
137
  label?: string;
138
+ delay?: number;
139
+ /** Stacked-mode only: CSS selector for the element to inject before (top) or after (bottom).
140
+ * Falls back to auto-detect when omitted. */
141
+ anchor?: string;
142
+ bg?: string;
143
+ border?: string;
144
+ radius?: number;
145
+ margin?: number;
146
+ shadow?: 'none' | 'sm' | 'md' | 'lg';
147
+ titleColor?: string;
148
+ titleSize?: number;
149
+ titleWeight?: 400 | 500 | 600 | 700;
150
+ bodyColor?: string;
151
+ bodySize?: number;
152
+ bodyWeight?: 400 | 500 | 600 | 700;
153
+ ctaBg?: string;
154
+ ctaColor?: string;
155
+ ctaSize?: number;
156
+ ctaWeight?: 400 | 500 | 600 | 700;
157
+ ctaRadius?: number;
158
+ iconSize?: number;
159
+ iconRadius?: number;
160
+ hideIcon?: boolean;
161
+ hideClose?: boolean;
162
+ hideBody?: boolean;
163
+ customClass?: string;
128
164
  }
129
165
  /** In-app message from the API */
130
166
  interface Message {
@@ -357,8 +393,41 @@ declare class Deferred {
357
393
  constructor(client: HttpClient);
358
394
  /** Claim a deferred deep link by referrer token (from Play Store referrer or clipboard) */
359
395
  claimByToken(token: string): Promise<DeferredLink | null>;
396
+ /**
397
+ * Recover the link that led here, once.
398
+ *
399
+ * There is no Play Install Referrer on the web, so this is signal matching
400
+ * with the bookkeeping that makes calling it safe. That bookkeeping is the
401
+ * point: a claim is consumed the first time it succeeds, so an app calling
402
+ * claimBySignals on every page load asks again after the answer is already
403
+ * spent, and every one of those asks is recorded as a miss. The match rate on
404
+ * the dashboard then falls towards zero while the integration is working
405
+ * correctly, which is a hard thing to diagnose from the outside.
406
+ *
407
+ * Call it once on first run. Calling it again is free after the first.
408
+ *
409
+ * Named to match the Android, React Native and Flutter SDKs, where the same
410
+ * call also tries the install referrer before falling back to here.
411
+ */
412
+ claimDeferredLink(options: {
413
+ appspaceId: string;
414
+ /** Claim again even if an attempt was already recorded. For tests. */
415
+ force?: boolean;
416
+ }): Promise<DeferredLink | null>;
417
+ private alreadyAttempted;
418
+ private rememberAttempt;
360
419
  /** Claim a deferred deep link by device signal matching */
361
420
  claimBySignals(options: ClaimBySignalsOptions): Promise<DeferredLink | null>;
421
+ /**
422
+ * The signal claim, with whether the server actually answered.
423
+ *
424
+ * `settled` separates "nothing is waiting for this device", which no amount
425
+ * of asking will change, from "the request never got there". Both surface as
426
+ * null to callers of claimBySignals, but claimDeferredLink has to tell them
427
+ * apart: recording an attempt that never reached the server would spend an
428
+ * install's one chance at attribution on a dropped connection.
429
+ */
430
+ private attemptSignals;
362
431
  }
363
432
 
364
433
  declare class Tolinku {
package/dist/index.d.ts CHANGED
@@ -98,6 +98,8 @@ interface ClaimBySignalsOptions {
98
98
  language?: string;
99
99
  screenWidth?: number;
100
100
  screenHeight?: number;
101
+ /** Defaults to `window.devicePixelRatio`. Override only if you report a custom screen size. */
102
+ devicePixelRatio?: number;
101
103
  }
102
104
  /** Banner config returned by the API */
103
105
  interface BannerConfig {
@@ -118,13 +120,47 @@ interface BannerItem {
118
120
  text_color: string;
119
121
  cta_text: string | null;
120
122
  position: string | null;
123
+ style: string | null;
124
+ shadow: string | null;
125
+ radius: number | null;
126
+ margin: number | null;
121
127
  dismiss_days: number | null;
122
128
  priority: number;
123
129
  }
124
- /** Options for showing a banner */
130
+ /** Options for showing a banner. All fields are optional.
131
+ * Resolution chain per value: option → server config → theme → built-in default. */
125
132
  interface ShowBannerOptions {
126
133
  position?: 'top' | 'bottom';
134
+ style?: 'pinned' | 'floating' | 'stacked';
135
+ animation?: 'slide' | 'fade' | 'pop' | 'none';
136
+ theme?: 'light' | 'dark';
127
137
  label?: string;
138
+ delay?: number;
139
+ /** Stacked-mode only: CSS selector for the element to inject before (top) or after (bottom).
140
+ * Falls back to auto-detect when omitted. */
141
+ anchor?: string;
142
+ bg?: string;
143
+ border?: string;
144
+ radius?: number;
145
+ margin?: number;
146
+ shadow?: 'none' | 'sm' | 'md' | 'lg';
147
+ titleColor?: string;
148
+ titleSize?: number;
149
+ titleWeight?: 400 | 500 | 600 | 700;
150
+ bodyColor?: string;
151
+ bodySize?: number;
152
+ bodyWeight?: 400 | 500 | 600 | 700;
153
+ ctaBg?: string;
154
+ ctaColor?: string;
155
+ ctaSize?: number;
156
+ ctaWeight?: 400 | 500 | 600 | 700;
157
+ ctaRadius?: number;
158
+ iconSize?: number;
159
+ iconRadius?: number;
160
+ hideIcon?: boolean;
161
+ hideClose?: boolean;
162
+ hideBody?: boolean;
163
+ customClass?: string;
128
164
  }
129
165
  /** In-app message from the API */
130
166
  interface Message {
@@ -357,8 +393,41 @@ declare class Deferred {
357
393
  constructor(client: HttpClient);
358
394
  /** Claim a deferred deep link by referrer token (from Play Store referrer or clipboard) */
359
395
  claimByToken(token: string): Promise<DeferredLink | null>;
396
+ /**
397
+ * Recover the link that led here, once.
398
+ *
399
+ * There is no Play Install Referrer on the web, so this is signal matching
400
+ * with the bookkeeping that makes calling it safe. That bookkeeping is the
401
+ * point: a claim is consumed the first time it succeeds, so an app calling
402
+ * claimBySignals on every page load asks again after the answer is already
403
+ * spent, and every one of those asks is recorded as a miss. The match rate on
404
+ * the dashboard then falls towards zero while the integration is working
405
+ * correctly, which is a hard thing to diagnose from the outside.
406
+ *
407
+ * Call it once on first run. Calling it again is free after the first.
408
+ *
409
+ * Named to match the Android, React Native and Flutter SDKs, where the same
410
+ * call also tries the install referrer before falling back to here.
411
+ */
412
+ claimDeferredLink(options: {
413
+ appspaceId: string;
414
+ /** Claim again even if an attempt was already recorded. For tests. */
415
+ force?: boolean;
416
+ }): Promise<DeferredLink | null>;
417
+ private alreadyAttempted;
418
+ private rememberAttempt;
360
419
  /** Claim a deferred deep link by device signal matching */
361
420
  claimBySignals(options: ClaimBySignalsOptions): Promise<DeferredLink | null>;
421
+ /**
422
+ * The signal claim, with whether the server actually answered.
423
+ *
424
+ * `settled` separates "nothing is waiting for this device", which no amount
425
+ * of asking will change, from "the request never got there". Both surface as
426
+ * null to callers of claimBySignals, but claimDeferredLink has to tell them
427
+ * apart: recording an attempt that never reached the server would spend an
428
+ * install's one chance at attribution on a dropped connection.
429
+ */
430
+ private attemptSignals;
362
431
  }
363
432
 
364
433
  declare class Tolinku {