@posthog/browser-common 0.4.0 → 0.5.1

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
@@ -54,17 +54,35 @@ synchronous callback into idempotent teardown.
54
54
 
55
55
  What an extension is given in `setup` — the adapter shared by extensions on that host SDK instance:
56
56
 
57
- - **identity and session**: `distinctId`, `anonymousId`, `groups`, `session`
57
+ - **identity and session**: `distinctId`, `anonymousId`, `deviceId`, `groups`, `session`, `initialPersonProperties`
58
+ - **SDK metadata**: `library`
58
59
  - **events**: `capture(...)`, `registerDynamicEventProperties(...)`, `onEvent(...)`
59
60
  - **server config**: `onRemoteConfig(...)`
60
- - **transport**: `projectToken`, `sendRequest(path, init?)`
61
+ - **transport**: `projectToken`, `sendRequest(path, init?)`, including `compression` and `sentAt` options
61
62
  - **storage and logging**: `kv`, `logger`
62
63
 
63
- Identity, session, and the public project token are always-ready synchronous
64
- reads. Operations that may perform I/O, including `capture`, `sendRequest`,
65
- and `kv`, are awaitable. `onRemoteConfig` immediately replays the latest known
66
- success or failure and then reports subsequent outcomes. Extensions that want a
67
- named log prefix can create a child with `client.logger.createLogger('[myExtension]')`.
64
+ Identity, session, SDK metadata, and the public project token are always-ready synchronous reads. `capture` and
65
+ `sendRequest` are awaitable. For `sendRequest`, `sentAt` controls `sent_at` placement on POST requests; GET query mode
66
+ uses the cache-busting `_` parameter instead, and GET body mode has no effect. `onRemoteConfig` immediately replays the
67
+ latest known success or failure and then reports subsequent outcomes. Extensions that want a named log prefix can
68
+ create a child with `client.logger.createLogger('[myExtension]')`.
69
+
70
+ Initialize KV during asynchronous setup before using its synchronous buffer:
71
+
72
+ ```ts
73
+ await client.kv.initialize()
74
+ const state = client.kv.get<{ first: boolean; second: string }>(['first', 'second'])
75
+ client.kv.set({ ...state, first: true })
76
+ client.kv.remove(['first', 'second'])
77
+ ```
78
+
79
+ Initialization is idempotent and may be asynchronous while a host hydrates its buffer. After it completes, reads,
80
+ writes, and removals are synchronous; batch reads, object writes, and multi-key removals operate on related values
81
+ coherently. The host owns ordered durable flushing.
82
+
83
+ KV keys map directly to shared host persistence: reset clears them, collisions can overwrite host state, and unknown
84
+ keys may be captured as event properties. Use stable extension-owned keys with an explicit exposure policy, and do not
85
+ store sensitive values unless their transmission is approved.
68
86
 
69
87
  ### Host runtime
70
88
 
package/dist/client.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Logger } from '@posthog/core';
2
2
  import type { Properties } from '@posthog/types';
3
+ import type { Compression } from './types/compression';
3
4
  import type { Disposable } from './disposable';
4
5
  import type { KeyValueStore } from './persistence';
5
6
  import type { Listener } from './pubsub';
@@ -26,7 +27,7 @@ export interface CapturedEventInfo {
26
27
  }
27
28
  /** Per-call capture overrides, mirroring the client's public capture options. */
28
29
  export interface CaptureOptions {
29
- /** Override the event timestamp sent to PostHog. */
30
+ /** Override the event timestamp sent to PostHog. UTC is preferred; non-UTC input is converted to UTC. */
30
31
  timestamp?: Date;
31
32
  /** Override the event UUID used for de-duplication. */
32
33
  uuid?: string;
@@ -66,6 +67,10 @@ export interface SendRequestInit {
66
67
  transport?: RequestTransport;
67
68
  /** Abort the request if it does not complete within this many milliseconds. */
68
69
  timeoutMs?: number;
70
+ /** Compression used by the browser transport. */
71
+ compression?: Compression | 'best-available';
72
+ /** Where POST requests add `sent_at`. For GET, `query` adds the cache-busting `_` parameter and `body` has no effect. */
73
+ sentAt?: 'body' | 'query';
69
74
  }
70
75
  /**
71
76
  * The host SDK surface handed to an extension in `setup`. A conforming host
@@ -77,6 +82,15 @@ export interface Client {
77
82
  readonly distinctId: string;
78
83
  /** The anonymous device id carried across identify calls. */
79
84
  readonly anonymousId: string;
85
+ /** The actual persisted device id, absent in cookieless contexts. */
86
+ readonly deviceId: string | undefined;
87
+ /** Live host SDK metadata. */
88
+ readonly library: {
89
+ readonly name: string;
90
+ readonly version: string;
91
+ };
92
+ /** Initial person properties used for feature evaluation. */
93
+ readonly initialPersonProperties: DeepReadonly<Record<string, unknown>>;
80
94
  /** Active group memberships attached to events as `$groups`. */
81
95
  readonly groups: DeepReadonly<Record<string, string>>;
82
96
  /** The current session, created on first read if needed. */
@@ -93,7 +107,7 @@ export interface Client {
93
107
  readonly projectToken: string;
94
108
  /** Sends a request through the host SDK's transport. */
95
109
  sendRequest(path: string, init?: SendRequestInit): Promise<ApiResponse>;
96
- /** Awaitable key-value storage backed by the host client's persistence. */
110
+ /** Initializable, synchronously buffered key-value storage backed by the host client's persistence. */
97
111
  readonly kv: KeyValueStore;
98
112
  /** Logger that follows the host client's debug/noise policy. */
99
113
  readonly logger: Logger;
package/dist/config.js CHANGED
@@ -26,7 +26,7 @@ __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
27
  default: ()=>__WEBPACK_DEFAULT_EXPORT__
28
28
  });
29
- const packageVersion = "0.4.0";
29
+ const packageVersion = "0.5.1";
30
30
  const Config = {
31
31
  DEBUG: false,
32
32
  LIB_VERSION: packageVersion,
package/dist/config.mjs CHANGED
@@ -1,4 +1,4 @@
1
- const packageVersion = "0.4.0";
1
+ const packageVersion = "0.5.1";
2
2
  const Config = {
3
3
  DEBUG: false,
4
4
  LIB_VERSION: packageVersion,
@@ -1,7 +1,8 @@
1
1
  /**
2
- * Key-value store for small extension state. Implementations backed by
3
- * synchronous persistence may return immediately, while asynchronous stores
4
- * (for example IndexedDB) may return promises. Consumers can await either.
2
+ * Key-value store for small extension state. A host may initialize an asynchronous
3
+ * backend before exposing synchronous operations over its in-memory buffer. Writes
4
+ * must update that buffer before returning; ordered durable flushing remains the
5
+ * host's responsibility. Reads treat `undefined` values as absent.
5
6
  *
6
7
  * Keys map verbatim to the host client's shared persistence. In browser-v1,
7
8
  * unknown keys are normally included as event properties, collisions overwrite
@@ -11,17 +12,19 @@
11
12
  * JSON-serializable.
12
13
  */
13
14
  export interface KeyValueStore {
15
+ /** Populate the in-memory buffer from durable storage. Calls are idempotent. */
16
+ initialize(): void | Promise<void>;
17
+ /** Read several initialized values in one operation. Missing keys are omitted. */
18
+ get<T extends object>(keys: readonly (keyof T & string)[]): Partial<T>;
19
+ /** Read one initialized value by key, returning `undefined` when it is missing. */
20
+ get<T = unknown>(key: string): T | undefined;
14
21
  /**
15
- * Read a value by key.
16
- *
17
- * @returns The stored value, or `undefined` when the key is missing.
22
+ * Immediately update the initialized buffer. `null` is durable; `undefined` is
23
+ * accepted for compatibility but treated as absent by reads and is not portable.
18
24
  */
19
- get<T = unknown>(key: string): T | undefined | Promise<T | undefined>;
20
- /**
21
- * Forward a JSON-serializable value, including nullish values, to the host's
22
- * native persistence. `undefined` is not portable or durable storage.
23
- */
24
- set(key: string, value: unknown): void | Promise<void>;
25
- /** Remove a value by key. This is the portable deletion operation. */
26
- remove(key: string): void | Promise<void>;
25
+ set(key: string, value: unknown): void;
26
+ /** Coherently update several related values in the initialized buffer. */
27
+ set(values: Record<string, unknown>): void;
28
+ /** Remove one or several values from the initialized buffer in one operation. */
29
+ remove(keyOrKeys: string | readonly string[]): void;
27
30
  }
@@ -0,0 +1,3 @@
1
+ export type MaybePromise<T> = T | Promise<T>;
2
+ /** Chain sync and async values without deferring synchronous work to a microtask. */
3
+ export declare const continueWith: <T, R>(result: MaybePromise<T>, callback: (value: T) => MaybePromise<R>) => MaybePromise<R>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ continueWith: ()=>continueWith
28
+ });
29
+ const continueWith = (result, callback)=>{
30
+ const promise = result;
31
+ return promise?.then ? promise.then(callback) : callback(result);
32
+ };
33
+ exports.continueWith = __webpack_exports__.continueWith;
34
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
35
+ "continueWith"
36
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
37
+ Object.defineProperty(exports, '__esModule', {
38
+ value: true
39
+ });
@@ -0,0 +1,5 @@
1
+ const continueWith = (result, callback)=>{
2
+ const promise = result;
3
+ return promise?.then ? promise.then(callback) : callback(result);
4
+ };
5
+ export { continueWith };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/browser-common",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Internal shared browser utilities and extension primitives for PostHog Browser SDKs",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -65,8 +65,8 @@
65
65
  }
66
66
  },
67
67
  "dependencies": {
68
- "@posthog/core": "^1.46.8",
69
- "@posthog/types": "^1.402.0"
68
+ "@posthog/core": "^1.48.10",
69
+ "@posthog/types": "^1.405.2"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@rslib/core": "0.10.6",