pgp-sdk 0.1.0 → 0.1.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
@@ -4,7 +4,9 @@ Isomorphic (Node.js + browser) event ingestion SDK for the PGP platform.
4
4
 
5
5
  ## Install
6
6
 
7
- Copy/`npm pack` from this directory (internal package, not on npm).
7
+ ```bash
8
+ npm i pgp-sdk
9
+ ```
8
10
 
9
11
  ## Node.js
10
12
 
@@ -22,10 +24,20 @@ await pgp.close(); // flush on shutdown
22
24
 
23
25
  ## Browser
24
26
 
27
+ With a bundler (vite/webpack), identical to Node:
28
+
29
+ ```ts
30
+ import { PgpClient } from "pgp-sdk";
31
+ const pgp = new PgpClient({ apiKey: "pgp_..." });
32
+ pgp.capture("page_view");
33
+ ```
34
+
35
+ No bundler — script tag via CDN, exposes a `PgpSDK` global:
36
+
25
37
  ```html
26
- <script type="module">
27
- import { PgpClient } from "./node_modules/pgp-sdk/dist/index.js";
28
- const pgp = new PgpClient({ apiKey: "pgp_..." });
38
+ <script src="https://unpkg.com/pgp-sdk/dist/index.global.js"></script>
39
+ <script>
40
+ const pgp = new PgpSDK.PgpClient({ apiKey: "pgp_..." });
29
41
  pgp.capture("page_view");
30
42
  </script>
31
43
  ```
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var PgpSDK = (() => {
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ PgpClient: () => PgpClient,
25
+ createClient: () => createClient,
26
+ default: () => index_default
27
+ });
28
+ var ANON_KEY = "pgp_anon_id";
29
+ function uuid() {
30
+ return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
31
+ }
32
+ function anonId() {
33
+ try {
34
+ let id = localStorage.getItem(ANON_KEY);
35
+ if (!id) {
36
+ id = uuid();
37
+ localStorage.setItem(ANON_KEY, id);
38
+ }
39
+ return id;
40
+ } catch {
41
+ return uuid();
42
+ }
43
+ }
44
+ var PgpClient = class {
45
+ #opts;
46
+ #fetch;
47
+ #queue = [];
48
+ #flushing = Promise.resolve();
49
+ #userId;
50
+ #timer;
51
+ #onHide;
52
+ constructor(opts) {
53
+ if (!opts.apiKey) throw new Error("pgp: apiKey is required");
54
+ this.#opts = {
55
+ apiKey: opts.apiKey,
56
+ baseUrl: (opts.baseUrl ?? "https://pgp.int.wepromotion.cn").replace(/\/$/, ""),
57
+ flushAt: opts.flushAt ?? 20,
58
+ flushInterval: opts.flushInterval ?? 5e3
59
+ };
60
+ this.#fetch = opts.fetchFn ?? fetch.bind(globalThis);
61
+ this.#userId = opts.userId ?? anonId();
62
+ if (typeof document !== "undefined") {
63
+ this.#onHide = () => {
64
+ if (this.#queue.length) void this.#flush(true);
65
+ };
66
+ document.addEventListener("visibilitychange", this.#onHide);
67
+ window.addEventListener("pagehide", this.#onHide);
68
+ }
69
+ }
70
+ /** Track the logged-in user (switches future events to this id). */
71
+ setUserId(userId) {
72
+ this.#userId = userId;
73
+ }
74
+ /** Queue an event. Flushing happens automatically. */
75
+ capture(name, properties) {
76
+ if (!this.#userId) {
77
+ console.error(`pgp: dropping event "${name}" \u2014 no user id`);
78
+ return;
79
+ }
80
+ this.#queue.push({ user_id: this.#userId, name, properties });
81
+ if (!this.#timer) {
82
+ this.#timer = setInterval(() => void this.flush(), this.#opts.flushInterval);
83
+ this.#timer.unref?.();
84
+ }
85
+ if (this.#queue.length >= this.#opts.flushAt) void this.flush();
86
+ }
87
+ /** Flush now. Concurrent calls share one request. Never throws. */
88
+ flush() {
89
+ return this.#flushing = this.#flushing.then(() => this.#flush(false));
90
+ }
91
+ /** Flush and stop timers/listeners. Call on shutdown. */
92
+ async close() {
93
+ if (this.#timer) clearInterval(this.#timer);
94
+ if (this.#onHide) {
95
+ document.removeEventListener("visibilitychange", this.#onHide);
96
+ window.removeEventListener("pagehide", this.#onHide);
97
+ }
98
+ await this.flush();
99
+ }
100
+ async #flush(keepalive) {
101
+ if (!this.#queue.length) return;
102
+ const events = this.#queue;
103
+ this.#queue = [];
104
+ try {
105
+ const res = await this.#fetch(`${this.#opts.baseUrl}/api/events/batch`, {
106
+ method: "POST",
107
+ headers: {
108
+ "content-type": "application/json",
109
+ authorization: `Bearer ${this.#opts.apiKey}`
110
+ },
111
+ body: JSON.stringify({ events }),
112
+ keepalive
113
+ // lets the request survive page unload
114
+ });
115
+ if (!res.ok) throw new Error(`pgp: flush failed with HTTP ${res.status}`);
116
+ if (!this.#queue.length && this.#timer) {
117
+ clearInterval(this.#timer);
118
+ this.#timer = void 0;
119
+ }
120
+ } catch (err) {
121
+ this.#queue = events.concat(this.#queue);
122
+ console.error(err instanceof Error ? err.message : err);
123
+ }
124
+ }
125
+ };
126
+ function createClient(opts) {
127
+ return new PgpClient(opts);
128
+ }
129
+ var index_default = { createClient, PgpClient };
130
+ return __toCommonJS(index_exports);
131
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgp-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Isomorphic (Node.js + browser) event ingestion SDK for the PGP platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "files": ["dist"],
17
17
  "scripts": {
18
- "build": "tsup src/index.ts --format esm,cjs --dts --clean",
18
+ "build": "tsup src/index.ts --format esm,cjs,iife --global-name PgpSDK --dts --clean",
19
19
  "test": "node --test 'test/*.test.ts'",
20
20
  "prepublishOnly": "npm test && npm run build"
21
21
  },