@posthog/browser-common 0.0.0 → 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/README.md +114 -28
- package/dist/client.d.ts +136 -0
- package/dist/client.js +18 -0
- package/dist/client.mjs +0 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.js +43 -0
- package/dist/config.mjs +9 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +44 -0
- package/dist/constants.mjs +4 -0
- package/dist/disposable.d.ts +13 -0
- package/dist/disposable.js +18 -0
- package/dist/disposable.mjs +0 -0
- package/dist/extension.d.ts +45 -0
- package/dist/extension.js +18 -0
- package/dist/extension.mjs +0 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +36 -0
- package/dist/index.mjs +2 -0
- package/dist/persistence.d.ts +24 -0
- package/dist/persistence.js +18 -0
- package/dist/persistence.mjs +0 -0
- package/dist/pubsub.d.ts +28 -0
- package/dist/pubsub.js +67 -0
- package/dist/pubsub.mjs +33 -0
- package/dist/token.d.ts +21 -0
- package/dist/token.js +18 -0
- package/dist/token.mjs +0 -0
- package/dist/utils/array-at-polyfill.d.ts +1 -0
- package/dist/utils/array-at-polyfill.js +16 -0
- package/dist/utils/array-at-polyfill.mjs +11 -0
- package/dist/utils/autocapture-utils.d.ts +23 -0
- package/dist/utils/autocapture-utils.js +479 -0
- package/dist/utils/autocapture-utils.mjs +385 -0
- package/dist/utils/blocked-uas.d.ts +17 -0
- package/dist/utils/blocked-uas.js +54 -0
- package/dist/utils/blocked-uas.mjs +14 -0
- package/dist/utils/cookie-utils.d.ts +1 -0
- package/dist/utils/cookie-utils.js +49 -0
- package/dist/utils/cookie-utils.mjs +15 -0
- package/dist/utils/device-model-utils.d.ts +8 -0
- package/dist/utils/device-model-utils.js +52 -0
- package/dist/utils/device-model-utils.mjs +18 -0
- package/dist/utils/element-utils.d.ts +5 -0
- package/dist/utils/element-utils.js +67 -0
- package/dist/utils/element-utils.mjs +21 -0
- package/dist/utils/elements-chain-utils.d.ts +4 -0
- package/dist/utils/elements-chain-utils.js +79 -0
- package/dist/utils/elements-chain-utils.mjs +36 -0
- package/dist/utils/encode-utils.d.ts +8 -0
- package/dist/utils/encode-utils.js +39 -0
- package/dist/utils/encode-utils.mjs +5 -0
- package/dist/utils/event-utils.d.ts +24 -0
- package/dist/utils/event-utils.js +344 -0
- package/dist/utils/event-utils.mjs +246 -0
- package/dist/utils/general-utils.d.ts +30 -0
- package/dist/utils/general-utils.js +191 -0
- package/dist/utils/general-utils.mjs +118 -0
- package/dist/utils/globals.d.ts +25 -0
- package/dist/utils/globals.js +75 -0
- package/dist/utils/globals.mjs +14 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.js +83 -0
- package/dist/utils/logger.mjs +36 -0
- package/dist/utils/matcher-utils.d.ts +3 -0
- package/dist/utils/matcher-utils.js +63 -0
- package/dist/utils/matcher-utils.mjs +26 -0
- package/dist/utils/property-utils.d.ts +23 -0
- package/dist/utils/property-utils.js +108 -0
- package/dist/utils/property-utils.mjs +65 -0
- package/dist/utils/prototype-utils.d.ts +7 -0
- package/dist/utils/prototype-utils.js +64 -0
- package/dist/utils/prototype-utils.mjs +27 -0
- package/dist/utils/regex-utils.d.ts +2 -0
- package/dist/utils/regex-utils.js +54 -0
- package/dist/utils/regex-utils.mjs +17 -0
- package/dist/utils/request-utils.d.ts +15 -0
- package/dist/utils/request-utils.js +153 -0
- package/dist/utils/request-utils.mjs +95 -0
- package/dist/utils/simple-event-emitter.d.ts +5 -0
- package/dist/utils/simple-event-emitter.js +51 -0
- package/dist/utils/simple-event-emitter.mjs +17 -0
- package/dist/utils/stylesheet-loader.d.ts +7 -0
- package/dist/utils/stylesheet-loader.js +53 -0
- package/dist/utils/stylesheet-loader.mjs +19 -0
- package/dist/utils/type-utils.d.ts +2 -0
- package/dist/utils/type-utils.js +41 -0
- package/dist/utils/type-utils.mjs +4 -0
- package/dist/utils/url-targeting-utils.d.ts +28 -0
- package/dist/utils/url-targeting-utils.js +56 -0
- package/dist/utils/url-targeting-utils.mjs +19 -0
- package/dist/utils/uuidv7.d.ts +43 -0
- package/dist/utils/uuidv7.js +172 -0
- package/dist/utils/uuidv7.js.LICENSE.txt +9 -0
- package/dist/utils/uuidv7.mjs +132 -0
- package/dist/utils/uuidv7.mjs.LICENSE.txt +9 -0
- package/package.json +79 -8
package/README.md
CHANGED
|
@@ -1,45 +1,131 @@
|
|
|
1
1
|
# @posthog/browser-common
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Internal shared browser utilities and extension primitives for PostHog JavaScript
|
|
4
|
+
SDKs. This package is published so unbundled SDK outputs can resolve it at
|
|
5
|
+
runtime, but it is not a public API surface and does not provide compatibility
|
|
6
|
+
guarantees outside PostHog SDK packages.
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
The shared extension contract includes the interface an extension implements
|
|
9
|
+
(`Extension`), the host capabilities it is handed (`Client`), and small shared
|
|
10
|
+
runtime primitives such as `Publisher`.
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
An extension written against this contract runs unchanged across major versions of the web SDK:
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
- **v1** is synchronous; extensions are registered statically.
|
|
15
|
+
- **v2** is asynchronous; extensions are loaded dynamically.
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
2. Enable secure, token-less publishing from CI/CD workflows
|
|
14
|
-
3. Establish provenance for packages published under this name
|
|
17
|
+
Each SDK provides a _client adapter_ that implements `Client` over its own
|
|
18
|
+
internals, so extension code never depends on a specific SDK.
|
|
15
19
|
|
|
16
|
-
##
|
|
20
|
+
## Concepts
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
### `Extension`
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
What you implement. The host calls only `setup` and `dispose`:
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
```ts
|
|
27
|
+
import type { Disposable, Extension } from '@posthog/browser-common'
|
|
23
28
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
3. Specify the repository and workflow that should be allowed to publish
|
|
27
|
-
4. Use the configured workflow to publish your actual package
|
|
29
|
+
export function webContext(): Extension {
|
|
30
|
+
let removeProperties: Disposable | undefined
|
|
28
31
|
|
|
29
|
-
|
|
32
|
+
return {
|
|
33
|
+
name: 'webContext',
|
|
34
|
+
setup(client) {
|
|
35
|
+
removeProperties = client.registerDynamicEventProperties(() => ({
|
|
36
|
+
$current_url: window.location.href,
|
|
37
|
+
}))
|
|
38
|
+
},
|
|
39
|
+
dispose() {
|
|
40
|
+
removeProperties?.dispose()
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
30
45
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- Should not be installed as a dependency
|
|
35
|
-
- Exists only for administrative purposes
|
|
46
|
+
`setup(client)` may be async (read async state before you're ready); `dispose()`
|
|
47
|
+
may be async (final flush). Static config the app sets goes in your constructor,
|
|
48
|
+
not on the `Client`.
|
|
36
49
|
|
|
37
|
-
|
|
50
|
+
Anything in `setup` that returns a `Disposable` must be held by the extension
|
|
51
|
+
and disposed in `dispose()`.
|
|
38
52
|
|
|
39
|
-
|
|
40
|
-
- [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
|
|
41
|
-
- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
|
53
|
+
### `Client`
|
|
42
54
|
|
|
43
|
-
|
|
55
|
+
What an extension is given in `setup` — the host's capability surface:
|
|
44
56
|
|
|
45
|
-
**
|
|
57
|
+
- **identity & session** (synchronous reads): `distinctId`, `anonymousId`, `groups`, `session`
|
|
58
|
+
- **events**: `capture(...)`, `registerDynamicEventProperties(...)` (contribute properties), `onEvent(...)` (observe)
|
|
59
|
+
- **transport**: `apiRequest(path, init?)`
|
|
60
|
+
- **server config**: `getRemoteConfig()` (current), `onRemoteConfig(...)` (changes)
|
|
61
|
+
- **lifecycle**: `onNewSession(...)`
|
|
62
|
+
- **registry**: `getExtension(token)`
|
|
63
|
+
- **storage & logging**: `kv`, `logger`
|
|
64
|
+
|
|
65
|
+
Synchronous members are always-ready in-memory reads; everything that does I/O
|
|
66
|
+
or waits for readiness (`capture`, `apiRequest`, `kv`, `getRemoteConfig`) is
|
|
67
|
+
asynchronous.
|
|
68
|
+
|
|
69
|
+
### `Publisher`
|
|
70
|
+
|
|
71
|
+
Use `Publisher<T>` when an extension provides its own event stream to other
|
|
72
|
+
extensions or to app-facing controls. Keep the publisher private, expose only its
|
|
73
|
+
`listener`, and dispose it when the extension is torn down:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { Publisher, type Listener } from '@posthog/browser-common'
|
|
77
|
+
|
|
78
|
+
const changes = new Publisher<FeatureFlagsChange>()
|
|
79
|
+
|
|
80
|
+
export const onChange: Listener<FeatureFlagsChange> = changes.listener
|
|
81
|
+
|
|
82
|
+
changes.publish({ flag: 'beta-ui', value: true })
|
|
83
|
+
changes.dispose()
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Cross-extension dependencies
|
|
87
|
+
|
|
88
|
+
Extensions depend on one another through tokens, never implementation imports:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { FeatureFlags } from './feature-flags/token'
|
|
92
|
+
|
|
93
|
+
const flags = client.getExtension(FeatureFlags) // FeatureFlagsExtension | undefined
|
|
94
|
+
if (flags && (await flags.getFeatureFlag('beta-ui'))) {
|
|
95
|
+
/* … */
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
A token is implementation-free, so importing it never pulls the provider's code
|
|
100
|
+
into your bundle — each extension stays independently tree-shakable and lazily
|
|
101
|
+
loadable. An extension that provides a capability declares its token(s) in
|
|
102
|
+
`provides`.
|
|
103
|
+
|
|
104
|
+
## Utilities
|
|
105
|
+
|
|
106
|
+
Reusable browser utilities are exposed through `utils/*` subpaths, but they are
|
|
107
|
+
intentionally not re-exported from the package root or a utility barrel. Import
|
|
108
|
+
the exact file you need so lazy extension bundles do not pull in unrelated
|
|
109
|
+
helpers:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { createLogger } from '@posthog/browser-common/utils/logger'
|
|
113
|
+
import { formDataToQuery } from '@posthog/browser-common/utils/request-utils'
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Authoring
|
|
117
|
+
|
|
118
|
+
See the **`develop-extension`** skill
|
|
119
|
+
([`.agents/skills/develop-extension/SKILL.md`](./.agents/skills/develop-extension/SKILL.md))
|
|
120
|
+
for the full guide: the capability cheatsheet, the rules (enrichers are
|
|
121
|
+
synchronous, dispose your disposables, design for asynchronous readiness,
|
|
122
|
+
cross-extension state goes through `getExtension`, not shared storage), and the
|
|
123
|
+
v1 → `Client` porting map.
|
|
124
|
+
|
|
125
|
+
## Status
|
|
126
|
+
|
|
127
|
+
Early and internal. The package currently defines the extension contract, the
|
|
128
|
+
shared `Publisher` helper, and directly imported browser utilities under
|
|
129
|
+
`utils/*` subpaths. Additional shared runtime helpers — key-value stores, the
|
|
130
|
+
registry implementation, and a test `Client` — will land alongside the first
|
|
131
|
+
ported extension.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { Logger } from '@posthog/core';
|
|
2
|
+
import type { Disposable } from './disposable';
|
|
3
|
+
import type { KeyValueStore } from './persistence';
|
|
4
|
+
import type { Listener } from './pubsub';
|
|
5
|
+
import type { ExtensionToken } from './token';
|
|
6
|
+
/** The current session, stamped on events to tie them to a session and a browser tab. */
|
|
7
|
+
export interface SessionContext {
|
|
8
|
+
/** The stable session identifier attached to events captured during this session. */
|
|
9
|
+
sessionId: string;
|
|
10
|
+
/** The logical browser tab/window identifier attached alongside the session id. */
|
|
11
|
+
windowId: string;
|
|
12
|
+
/** When the session started, as a Unix timestamp in milliseconds. */
|
|
13
|
+
sessionStartTimestamp: number;
|
|
14
|
+
}
|
|
15
|
+
/** Why a new session started (a `reset` also starts a new session). */
|
|
16
|
+
export type NewSessionReason = 'initial' | 'reset' | 'idleTimeout' | 'maxLength' | 'crossTabAdoption';
|
|
17
|
+
/** Details emitted when the client starts or adopts a new session. */
|
|
18
|
+
export interface NewSessionInfo extends SessionContext {
|
|
19
|
+
/** The condition that caused this session to begin. */
|
|
20
|
+
reason: NewSessionReason;
|
|
21
|
+
}
|
|
22
|
+
/** A captured event, as observed by `onEvent`. */
|
|
23
|
+
export interface CapturedEventInfo {
|
|
24
|
+
/** The event name supplied to {@link Client.capture}. */
|
|
25
|
+
event: string;
|
|
26
|
+
/** The final event properties after client defaults and dynamic properties are applied. */
|
|
27
|
+
properties: Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
/** Per-call capture overrides, mirroring the client's public capture options. */
|
|
30
|
+
export interface CaptureOptions {
|
|
31
|
+
/** Override the event timestamp sent to PostHog. */
|
|
32
|
+
timestamp?: Date;
|
|
33
|
+
/** Override the event UUID used for de-duplication. */
|
|
34
|
+
uuid?: string;
|
|
35
|
+
/** Person properties to set, emitted as `$set`. */
|
|
36
|
+
set?: Record<string, unknown>;
|
|
37
|
+
/** Person properties to set if unset, emitted as `$set_once`. */
|
|
38
|
+
setOnce?: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
/** A minimal response from {@link Client.apiRequest}. */
|
|
41
|
+
export interface ApiResponse {
|
|
42
|
+
/** Whether the request completed with a 2xx status, or was queued for best-effort unload transport. */
|
|
43
|
+
ok: boolean;
|
|
44
|
+
/** The HTTP status code returned by the transport, or a client-defined best-effort status for unload sends. */
|
|
45
|
+
status: number;
|
|
46
|
+
/** Parse the response body as JSON; may be unavailable for best-effort unload requests. */
|
|
47
|
+
json(): Promise<unknown>;
|
|
48
|
+
/** Read the response body as text; may be unavailable for best-effort unload requests. */
|
|
49
|
+
text(): Promise<string>;
|
|
50
|
+
}
|
|
51
|
+
/** Options for sending a request through {@link Client.apiRequest}. */
|
|
52
|
+
export interface ApiRequestInit {
|
|
53
|
+
/** HTTP method to use; defaults to the client's normal request method for the endpoint. */
|
|
54
|
+
method?: 'GET' | 'POST';
|
|
55
|
+
/** JSON-serialized by the client. */
|
|
56
|
+
body?: unknown;
|
|
57
|
+
/** Query string parameters appended to the request URL. */
|
|
58
|
+
query?: Record<string, string>;
|
|
59
|
+
/**
|
|
60
|
+
* Mark this as a teardown send (pagehide / shutdown): the client picks the
|
|
61
|
+
* most reliable fire-and-forget transport available — `sendBeacon`, fetch
|
|
62
|
+
* `keepalive`, or sync XHR. The response is best-effort: `.json()` may be
|
|
63
|
+
* unusable (e.g. `sendBeacon` only reports "queued"), so callers must not
|
|
64
|
+
* depend on it.
|
|
65
|
+
*/
|
|
66
|
+
unload?: boolean;
|
|
67
|
+
/** Abort the request if it does not complete within this many milliseconds. */
|
|
68
|
+
timeoutMs?: number;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Server-provided configuration, as returned by the remote config response
|
|
72
|
+
* (sampling rates, suppression rules, feature enablement, quotas, …). A loose
|
|
73
|
+
* record by design — each extension reads only the keys it owns.
|
|
74
|
+
*/
|
|
75
|
+
export type RemoteConfig = Record<string, unknown>;
|
|
76
|
+
/**
|
|
77
|
+
* The host SDK's capability surface as seen by an extension — the client an
|
|
78
|
+
* extension is handed in `setup`. Each SDK (v1, v2) provides it as a client
|
|
79
|
+
* adapter over its own internals.
|
|
80
|
+
*
|
|
81
|
+
* Synchronous members are always-ready in-memory reads (identity, session);
|
|
82
|
+
* asynchronous members do I/O or wait for something to become ready
|
|
83
|
+
* (`capture`, `apiRequest`, `kv`, `getRemoteConfig`).
|
|
84
|
+
*/
|
|
85
|
+
export interface Client {
|
|
86
|
+
/** The id events are currently attributed to — the anonymous id, or the identified user's id after `identify`. */
|
|
87
|
+
readonly distinctId: string;
|
|
88
|
+
/** The anonymous device id; used before `identify` and carried on identify events as `$anon_distinct_id`. */
|
|
89
|
+
readonly anonymousId: string;
|
|
90
|
+
/** Active group memberships (group type → group key), attached to events as `$groups`. */
|
|
91
|
+
readonly groups: Record<string, string>;
|
|
92
|
+
/** The current session, created on first read if needed; reading does not extend or rotate it. */
|
|
93
|
+
readonly session: SessionContext;
|
|
94
|
+
/** Records an analytics event through the client's normal pipeline. */
|
|
95
|
+
capture(event: string, properties?: Record<string, unknown> | null, options?: CaptureOptions): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Registers a producer of properties merged into every captured event.
|
|
98
|
+
* Returns a {@link Disposable} that removes it; an extension disposes it in
|
|
99
|
+
* its own `dispose`. May be called more than once. The producer runs inline
|
|
100
|
+
* during event build, so it must be cheap and synchronous; it may return
|
|
101
|
+
* different properties each time (e.g. the current URL), and is recomputed
|
|
102
|
+
* per event rather than stored.
|
|
103
|
+
*/
|
|
104
|
+
registerDynamicEventProperties(producer: () => Record<string, unknown>): Disposable;
|
|
105
|
+
/**
|
|
106
|
+
* Sends a request to a PostHog endpoint; the client owns auth, headers, and
|
|
107
|
+
* transport (fetch / XHR / keepalive). `path` is relative to the configured
|
|
108
|
+
* API host, e.g. `/s/`, `/flags/`, `/api/surveys/`.
|
|
109
|
+
*/
|
|
110
|
+
apiRequest(path: string, init?: ApiRequestInit): Promise<ApiResponse>;
|
|
111
|
+
/**
|
|
112
|
+
* Resolves with the client's remote config once available, or `undefined`
|
|
113
|
+
* if the fetch failed (never rejects, never hangs).
|
|
114
|
+
* Re-readable: each call resolves with the current config, awaiting the
|
|
115
|
+
* first fetch if none has landed. `await` it in `setup` to block until
|
|
116
|
+
* config is known, or `.then()` it to reconfigure once it arrives; later
|
|
117
|
+
* changes arrive via `onRemoteConfig`.
|
|
118
|
+
*/
|
|
119
|
+
getRemoteConfig(): Promise<RemoteConfig | undefined>;
|
|
120
|
+
/** Fires when server-provided config arrives or changes. */
|
|
121
|
+
readonly onRemoteConfig: Listener<RemoteConfig>;
|
|
122
|
+
/** Fires for every captured event — hot path, keep handlers cheap and synchronous. */
|
|
123
|
+
readonly onEvent: Listener<CapturedEventInfo>;
|
|
124
|
+
/** Fires when a new session starts, including on reset (discriminate via `reason`). */
|
|
125
|
+
readonly onNewSession: Listener<NewSessionInfo>;
|
|
126
|
+
/**
|
|
127
|
+
* Resolves another registered extension by a capability token it provides, or
|
|
128
|
+
* `undefined` if nothing registered provides it (not installed, or not loaded
|
|
129
|
+
* yet). Lets one extension use another without importing its implementation.
|
|
130
|
+
*/
|
|
131
|
+
getExtension<T>(token: ExtensionToken<T>): T | undefined;
|
|
132
|
+
/** Async key-value storage scoped to this client instance and extension. */
|
|
133
|
+
readonly kv: KeyValueStore;
|
|
134
|
+
/** Logger that follows the host client's debug/noise policy. */
|
|
135
|
+
readonly logger: Logger;
|
|
136
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.r = (exports1)=>{
|
|
5
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
6
|
+
value: 'Module'
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
})();
|
|
13
|
+
var __webpack_exports__ = {};
|
|
14
|
+
__webpack_require__.r(__webpack_exports__);
|
|
15
|
+
for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
16
|
+
Object.defineProperty(exports, '__esModule', {
|
|
17
|
+
value: true
|
|
18
|
+
});
|
package/dist/client.mjs
ADDED
|
File without changes
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
default: ()=>__WEBPACK_DEFAULT_EXPORT__
|
|
28
|
+
});
|
|
29
|
+
const packageVersion = "0.2.0";
|
|
30
|
+
const Config = {
|
|
31
|
+
DEBUG: false,
|
|
32
|
+
LIB_VERSION: packageVersion,
|
|
33
|
+
LIB_NAME: 'browser-common',
|
|
34
|
+
JS_SDK_VERSION: packageVersion
|
|
35
|
+
};
|
|
36
|
+
const __WEBPACK_DEFAULT_EXPORT__ = Config;
|
|
37
|
+
exports["default"] = __webpack_exports__["default"];
|
|
38
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
39
|
+
"default"
|
|
40
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
41
|
+
Object.defineProperty(exports, '__esModule', {
|
|
42
|
+
value: true
|
|
43
|
+
});
|
package/dist/config.mjs
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
SDK_DIST_CHANNEL: ()=>SDK_DIST_CHANNEL,
|
|
28
|
+
TOOLBAR_CONTAINER_CLASS: ()=>TOOLBAR_CONTAINER_CLASS,
|
|
29
|
+
TOOLBAR_ID: ()=>TOOLBAR_ID
|
|
30
|
+
});
|
|
31
|
+
const TOOLBAR_ID = '__POSTHOG_TOOLBAR__';
|
|
32
|
+
const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container';
|
|
33
|
+
const SDK_DIST_CHANNEL = '$sdk_dist_channel';
|
|
34
|
+
exports.SDK_DIST_CHANNEL = __webpack_exports__.SDK_DIST_CHANNEL;
|
|
35
|
+
exports.TOOLBAR_CONTAINER_CLASS = __webpack_exports__.TOOLBAR_CONTAINER_CLASS;
|
|
36
|
+
exports.TOOLBAR_ID = __webpack_exports__.TOOLBAR_ID;
|
|
37
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
38
|
+
"SDK_DIST_CHANNEL",
|
|
39
|
+
"TOOLBAR_CONTAINER_CLASS",
|
|
40
|
+
"TOOLBAR_ID"
|
|
41
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
42
|
+
Object.defineProperty(exports, '__esModule', {
|
|
43
|
+
value: true
|
|
44
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Something with an async-capable teardown. `dispose` may be async so
|
|
3
|
+
* teardown can do final work — e.g. a last flush of buffered data — that the
|
|
4
|
+
* client can await before it finishes shutting down.
|
|
5
|
+
*/
|
|
6
|
+
export interface Disposable {
|
|
7
|
+
/**
|
|
8
|
+
* Release resources owned by this object. Implementations should be
|
|
9
|
+
* idempotent so callers can safely dispose during both extension teardown
|
|
10
|
+
* and client shutdown.
|
|
11
|
+
*/
|
|
12
|
+
dispose(): void | Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.r = (exports1)=>{
|
|
5
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
6
|
+
value: 'Module'
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
})();
|
|
13
|
+
var __webpack_exports__ = {};
|
|
14
|
+
__webpack_require__.r(__webpack_exports__);
|
|
15
|
+
for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
16
|
+
Object.defineProperty(exports, '__esModule', {
|
|
17
|
+
value: true
|
|
18
|
+
});
|
|
File without changes
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Disposable } from './disposable';
|
|
2
|
+
import type { Client } from './client';
|
|
3
|
+
import type { ExtensionToken } from './token';
|
|
4
|
+
/**
|
|
5
|
+
* A shared browser extension. The client calls only two things: `setup(client)`
|
|
6
|
+
* to start it and `dispose()` (from {@link Disposable}) to stop it. Everything
|
|
7
|
+
* an extension consumes flows the other way, through {@link Client}.
|
|
8
|
+
*
|
|
9
|
+
* `setup` may be async so an extension can read async-KV state or remote config
|
|
10
|
+
* before it is ready; the client awaits it. `name` is used for de-duplication
|
|
11
|
+
* and diagnostics. The `Disposable`s an extension creates in `setup` —
|
|
12
|
+
* enrichers, event listeners, timers — are its own to release: hold them and
|
|
13
|
+
* dispose them in `dispose`. The host disposes the extension; it does not track
|
|
14
|
+
* the extension's individual subscriptions.
|
|
15
|
+
*
|
|
16
|
+
* An extension that exposes app-facing controls extends `Extension` with named
|
|
17
|
+
* methods that share its state, e.g.:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* interface SessionReplayExtension extends Extension {
|
|
21
|
+
* startRecording(): void
|
|
22
|
+
* stopRecording(): void
|
|
23
|
+
* isActive(): boolean
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* The client still only calls `setup` and `dispose`; the controls are for the
|
|
28
|
+
* application that constructed the extension.
|
|
29
|
+
*/
|
|
30
|
+
export interface Extension extends Disposable {
|
|
31
|
+
/** Stable extension name used for diagnostics and de-duplication within a client instance. */
|
|
32
|
+
readonly name: string;
|
|
33
|
+
/**
|
|
34
|
+
* Capability tokens this extension answers to, so others can resolve it via
|
|
35
|
+
* `client.getExtension(token)`. The extension must be assignable to each
|
|
36
|
+
* token's provided type. Most extensions provide nothing.
|
|
37
|
+
*/
|
|
38
|
+
readonly provides?: readonly ExtensionToken<unknown>[];
|
|
39
|
+
/**
|
|
40
|
+
* Start the extension with the host client's capability surface. Called once
|
|
41
|
+
* after construction; return a promise when setup needs asynchronous state
|
|
42
|
+
* such as persisted data or remote config.
|
|
43
|
+
*/
|
|
44
|
+
setup(client: Client): void | Promise<void>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.r = (exports1)=>{
|
|
5
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
6
|
+
value: 'Module'
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
})();
|
|
13
|
+
var __webpack_exports__ = {};
|
|
14
|
+
__webpack_require__.r(__webpack_exports__);
|
|
15
|
+
for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
16
|
+
Object.defineProperty(exports, '__esModule', {
|
|
17
|
+
value: true
|
|
18
|
+
});
|
|
File without changes
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for browser extensions shared across PostHog JavaScript SDK
|
|
3
|
+
* clients.
|
|
4
|
+
*/
|
|
5
|
+
export type { Extension } from './extension';
|
|
6
|
+
export type { Disposable } from './disposable';
|
|
7
|
+
export type { ExtensionToken } from './token';
|
|
8
|
+
export type { Listener } from './pubsub';
|
|
9
|
+
export { Publisher } from './pubsub';
|
|
10
|
+
export type { Client, SessionContext, NewSessionReason, NewSessionInfo, CapturedEventInfo, CaptureOptions, ApiResponse, ApiRequestInit, RemoteConfig, } from './client';
|
|
11
|
+
export type { KeyValueStore } from './persistence';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
Publisher: ()=>external_pubsub_js_namespaceObject.Publisher
|
|
28
|
+
});
|
|
29
|
+
const external_pubsub_js_namespaceObject = require("./pubsub.js");
|
|
30
|
+
exports.Publisher = __webpack_exports__.Publisher;
|
|
31
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
32
|
+
"Publisher"
|
|
33
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
34
|
+
Object.defineProperty(exports, '__esModule', {
|
|
35
|
+
value: true
|
|
36
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Async key-value store for small extension state. Backed by whatever the
|
|
3
|
+
* client provides — a synchronous store resolves immediately, an asynchronous
|
|
4
|
+
* one (e.g. IndexedDB) does real I/O — so reads and writes are always awaited.
|
|
5
|
+
*
|
|
6
|
+
* The store is namespaced to the client instance, so keys are local to the
|
|
7
|
+
* extension and never collide with core SDK state. Values must be
|
|
8
|
+
* JSON-serializable; setting `null`/`undefined` removes the key.
|
|
9
|
+
*/
|
|
10
|
+
export interface KeyValueStore {
|
|
11
|
+
/**
|
|
12
|
+
* Read a value by key.
|
|
13
|
+
*
|
|
14
|
+
* @returns The stored value, or `undefined` when the key is missing.
|
|
15
|
+
*/
|
|
16
|
+
get<T = unknown>(key: string): Promise<T | undefined>;
|
|
17
|
+
/**
|
|
18
|
+
* Store a JSON-serializable value by key. Passing `null` or `undefined`
|
|
19
|
+
* removes the key instead of persisting that value.
|
|
20
|
+
*/
|
|
21
|
+
set(key: string, value: unknown): Promise<void>;
|
|
22
|
+
/** Remove a value by key. Resolves successfully when the key is already absent. */
|
|
23
|
+
remove(key: string): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.r = (exports1)=>{
|
|
5
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
6
|
+
value: 'Module'
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
})();
|
|
13
|
+
var __webpack_exports__ = {};
|
|
14
|
+
__webpack_require__.r(__webpack_exports__);
|
|
15
|
+
for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
16
|
+
Object.defineProperty(exports, '__esModule', {
|
|
17
|
+
value: true
|
|
18
|
+
});
|
|
File without changes
|