pulse-updates 1.3.7 → 1.3.8
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 +35 -2
- package/lib/commonjs/config.js.map +1 -1
- package/lib/commonjs/init.js +13 -1
- package/lib/commonjs/init.js.map +1 -1
- package/lib/commonjs/links.js +561 -61
- package/lib/commonjs/links.js.map +1 -1
- package/lib/commonjs/track.js +198 -75
- package/lib/commonjs/track.js.map +1 -1
- package/lib/module/config.js.map +1 -1
- package/lib/module/init.js +14 -2
- package/lib/module/init.js.map +1 -1
- package/lib/module/links.js +561 -61
- package/lib/module/links.js.map +1 -1
- package/lib/module/track.js +197 -75
- package/lib/module/track.js.map +1 -1
- package/lib/typescript/config.d.ts +6 -0
- package/lib/typescript/config.d.ts.map +1 -1
- package/lib/typescript/init.d.ts +1 -0
- package/lib/typescript/init.d.ts.map +1 -1
- package/lib/typescript/links.d.ts +49 -0
- package/lib/typescript/links.d.ts.map +1 -1
- package/lib/typescript/track.d.ts +17 -6
- package/lib/typescript/track.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +6 -0
- package/src/init.ts +16 -1
- package/src/links.ts +810 -40
- package/src/track.ts +283 -81
|
@@ -45,7 +45,7 @@ export interface TrackOptions {
|
|
|
45
45
|
flushIntervalMs?: number;
|
|
46
46
|
/** Events per request. The server refuses more than 100. */
|
|
47
47
|
maxBatch?: number;
|
|
48
|
-
/**
|
|
48
|
+
/** Best-effort events held before the oldest are dropped. Durable idempotent rows are never evicted. Default 500. */
|
|
49
49
|
maxQueue?: number;
|
|
50
50
|
/** Persists the outbox across process death. Use the same storage passed to initPulse. */
|
|
51
51
|
storage?: ConfigStorage;
|
|
@@ -53,9 +53,12 @@ export interface TrackOptions {
|
|
|
53
53
|
storageKey?: string;
|
|
54
54
|
/** Per-request timeout. Default 10s. */
|
|
55
55
|
timeoutMs?: number;
|
|
56
|
-
/** Maximum delivery attempts before
|
|
56
|
+
/** Maximum delivery attempts before a best-effort event is dropped. Durable idempotent events retry until server ACK. Default 10. */
|
|
57
57
|
maxAttempts?: number;
|
|
58
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Return false until analytics consent exists. No event is retained before consent. Consent is
|
|
60
|
+
* sampled at enqueue; an event already durably accepted remains eligible for later delivery.
|
|
61
|
+
*/
|
|
59
62
|
hasConsent?: () => boolean;
|
|
60
63
|
/** Only these property keys may leave the process. */
|
|
61
64
|
propertyAllowlist?: readonly string[];
|
|
@@ -84,12 +87,20 @@ export declare function configureTracking(opts: TrackOptions): void;
|
|
|
84
87
|
* caller has to wrap.
|
|
85
88
|
*/
|
|
86
89
|
export declare function track(event: string, props?: TrackedEventInput['props'], time?: Date): void;
|
|
90
|
+
/**
|
|
91
|
+
* Durably enqueue one logical event with a caller-owned UUID. Replaying the same id is safe:
|
|
92
|
+
* Pulse's server/read model deduplicates it, while the local outbox avoids duplicate rows that
|
|
93
|
+
* are still pending. `true` means the event is present in persistent storage, not delivered yet;
|
|
94
|
+
* once acknowledged, Track keeps it in that outbox through retries and process restarts until a
|
|
95
|
+
* successful server response removes it transactionally.
|
|
96
|
+
*/
|
|
97
|
+
export declare function trackIdempotent(eventId: string, event: string, props?: TrackedEventInput['props'], time?: Date): boolean;
|
|
87
98
|
/**
|
|
88
99
|
* Send what is queued. Returns how many events the server accepted.
|
|
89
100
|
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* after
|
|
101
|
+
* The batch remains in the durable queue while HTTP is in flight and is removed only after a
|
|
102
|
+
* successful response is also persisted locally. This intentionally permits duplicate replay
|
|
103
|
+
* after a crash, while a caller-owned event id lets the server/read model deduplicate it.
|
|
93
104
|
*/
|
|
94
105
|
export declare function flushEvents(): Promise<number>;
|
|
95
106
|
/** How many events are waiting — for a caller that wants to flush before backgrounding. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track.d.ts","sourceRoot":"","sources":["../../src/track.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE7D,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,aAAa,CAAC;IAEjC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,wBAAwB,CAAC;IAEpD,wDAAwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,
|
|
1
|
+
{"version":3,"file":"track.d.ts","sourceRoot":"","sources":["../../src/track.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE7D,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,aAAa,CAAC;IAEjC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,wBAAwB,CAAC;IAEpD,wDAAwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,qHAAqH;IACrH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,qIAAqI;IACrI,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAE3B,sDAAsD;IACtD,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEtC,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAErC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE;QAAE,gBAAgB,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK;YAAE,MAAM,EAAE,MAAM,IAAI,CAAA;SAAE,CAAA;KAAE,CAAC;IAE9G,+DAA+D;IAC/D,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAEvC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,cAAc,GAAG,YAAY,KAAK,IAAI,CAAC;IAE1F,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACrE,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAuCD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAY1D;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAE1F;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAClC,IAAI,CAAC,EAAE,IAAI,GACV,OAAO,CAIT;AA2GD;;;;;;GAMG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAiEnD;AAED,2FAA2F;AAC3F,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,eAAe,IAAI;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB,CAEA;AAED,qEAAqE;AACrE,wBAAgB,eAAe,IAAI,IAAI,CAStC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAOnC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pulse-updates",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.8",
|
|
4
4
|
"description": "Pulse app-experience SDK for React Native: updates, config, experiments, events, decisions and first-party links",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
package/src/config.ts
CHANGED
|
@@ -50,6 +50,12 @@ export type ConfigSignatureStatus = 'not-configured' | 'verified' | 'cached-veri
|
|
|
50
50
|
export interface ConfigStorage {
|
|
51
51
|
getString(key: string): string | null | undefined;
|
|
52
52
|
set(key: string, value: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* False when `set` only mirrors a write and schedules asynchronous persistence. Durable
|
|
55
|
+
* acknowledgement APIs must fail closed because process death may still lose that write.
|
|
56
|
+
* Omitted means the historical synchronous-storage contract.
|
|
57
|
+
*/
|
|
58
|
+
readonly supportsDurableSyncWrites?: boolean;
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
/**
|
package/src/init.ts
CHANGED
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
flushEvents,
|
|
46
46
|
getTrackingInfo,
|
|
47
47
|
track,
|
|
48
|
+
trackIdempotent,
|
|
48
49
|
type TrackedEventInput,
|
|
49
50
|
} from './track';
|
|
50
51
|
|
|
@@ -140,6 +141,12 @@ export interface PulseClient {
|
|
|
140
141
|
configUrl: string;
|
|
141
142
|
trackUrl: string;
|
|
142
143
|
track: (event: string, props?: TrackedEventInput['props'], time?: Date) => void;
|
|
144
|
+
trackIdempotent: (
|
|
145
|
+
eventId: string,
|
|
146
|
+
event: string,
|
|
147
|
+
props?: TrackedEventInput['props'],
|
|
148
|
+
time?: Date,
|
|
149
|
+
) => boolean;
|
|
143
150
|
flush: () => Promise<number>;
|
|
144
151
|
setUser: (userId?: string, attributes?: Record<string, string>) => void;
|
|
145
152
|
clearUser: () => void;
|
|
@@ -261,6 +268,7 @@ export function initPulse(opts: InitPulseOptions): PulseClient {
|
|
|
261
268
|
configUrl,
|
|
262
269
|
trackUrl,
|
|
263
270
|
track,
|
|
271
|
+
trackIdempotent,
|
|
264
272
|
flush: flushEvents,
|
|
265
273
|
setUser: (nextUserId, attributes) => {
|
|
266
274
|
userId = nextUserId?.trim() || undefined;
|
|
@@ -328,10 +336,17 @@ export async function initPulseAsync(
|
|
|
328
336
|
const loaded = await Promise.all(keys.map(async (key) => [key, await opts.storage.getItem(key)] as const));
|
|
329
337
|
const memory = new Map(loaded.filter((entry): entry is readonly [string, string] => entry[1] !== null));
|
|
330
338
|
const storage: ConfigStorage = {
|
|
339
|
+
supportsDurableSyncWrites: false,
|
|
331
340
|
getString: (key) => memory.get(key),
|
|
332
341
|
set: (key, value) => {
|
|
333
342
|
memory.set(key, value);
|
|
334
|
-
|
|
343
|
+
try {
|
|
344
|
+
void Promise.resolve(opts.storage.setItem(key, value)).catch((error) => {
|
|
345
|
+
try { opts.onError?.(error); } catch { /* diagnostics never break persistence */ }
|
|
346
|
+
});
|
|
347
|
+
} catch (error) {
|
|
348
|
+
try { opts.onError?.(error); } catch { /* diagnostics never break persistence */ }
|
|
349
|
+
}
|
|
335
350
|
},
|
|
336
351
|
};
|
|
337
352
|
return initPulse({ ...opts, storage });
|