@hanzo/event 0.3.39 → 0.3.40

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/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.3.37";
1
+ export declare const VERSION: string;
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO,WAAW,CAAA"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,OAAO,EAAE,MAAgB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzo/event",
3
- "version": "0.3.39",
3
+ "version": "0.3.40",
4
4
  "description": "Hanzo Event — the ONE telemetry client. Emits pageview/event/identify/group to the Hanzo Cloud event stream (POST /v1/event), AND reports errors to Sentry as real Sentry envelopes — the error plane needs a DSN, without one nothing reaches Sentry. First-touch attribution, beacon-on-unload, auto error capture, client-side secret/PII scrubbing, a shared event + goal vocabulary. Subsumes @sentry.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/",
package/src/core.ts CHANGED
@@ -699,6 +699,23 @@ function registry(): Map<string, Analytics> {
699
699
  return fresh
700
700
  }
701
701
 
702
+ /** resetClients drops the page's clients, so the next `createAnalytics` for a
703
+ * stream builds a fresh one.
704
+ *
705
+ * A real page loads once and never needs this. A TEST RUNNER is what it exists
706
+ * for: one document, many mounts, each meant to be its own page. The second one
707
+ * gets a client that already counted this location, so its pageview is
708
+ * correctly suppressed and the suite reads it as "nothing was emitted".
709
+ *
710
+ * It is exported so a suite calls this instead of reaching for the slot itself.
711
+ * A consumer that deletes the registry from its own code path takes the
712
+ * guarantee with it: `<Provider/>` unmount/remount is not a new page, and the
713
+ * fresh client it would get counts the same view again. */
714
+ export function resetClients(): void {
715
+ const g = globalThis as unknown as Record<symbol, Map<string, Analytics> | undefined>
716
+ delete g[CLIENTS]
717
+ }
718
+
702
719
  /** createAnalytics returns the client for a stream, building it on first ask.
703
720
  * This is the ONE way to get a client: `new Analytics` bypasses the registry
704
721
  * and is for tests and for a deliberately separate instance. */
package/src/index.ts CHANGED
@@ -7,7 +7,14 @@
7
7
  //
8
8
  // React apps use the './react' entry for the provider + hooks + error boundary.
9
9
 
10
- export { Analytics, createAnalytics, VERSION, getCohort, getFirstTouch } from './core'
10
+ export {
11
+ Analytics,
12
+ createAnalytics,
13
+ resetClients,
14
+ VERSION,
15
+ getCohort,
16
+ getFirstTouch,
17
+ } from './core'
11
18
  export { parseDsn, buildSentryEvent, buildEnvelope, framesFromStack } from './sentry'
12
19
  export { uuidv7, uuidv7Time } from './uid'
13
20
  export { PRODUCT_PROJECT, dsnForProduct } from './dsn'
@@ -8,7 +8,7 @@
8
8
  // Authorization at all (401, ingest_key_required) — because the library asked
9
9
  // first and had no key. Both batches held a $pageview for the same page.
10
10
  import { describe, it, expect, beforeEach } from 'vitest'
11
- import { Analytics, createAnalytics } from './core'
11
+ import { Analytics, createAnalytics, resetClients } from './core'
12
12
  import { PAGEVIEW } from './events'
13
13
  import type { Transport, WireEvent } from './types'
14
14
 
@@ -57,7 +57,7 @@ const app = () =>
57
57
 
58
58
  beforeEach(() => {
59
59
  tx = new FakeTransport()
60
- delete (globalThis as unknown as Record<symbol, unknown>)[Symbol.for('hanzo.event.clients')]
60
+ resetClients() // each `it` is its own page load
61
61
  window.history.replaceState(null, '', '/pricing')
62
62
  })
63
63
 
@@ -135,6 +135,18 @@ describe('one stream, one client', () => {
135
135
  expect(createAnalytics({ product: 'site', host: HOST })).not.toBe(own)
136
136
  })
137
137
 
138
+ // The registry is page state, and only a new page may drop it. A consumer that
139
+ // dropped it from its own code — @hanzogui/telemetry did this on every provider
140
+ // unmount — gives the next caller a client that has never seen this page, and
141
+ // the view is counted a second time. So the reset is named here, where a test
142
+ // runner can say "new page" and nothing else can say it by accident.
143
+ it('drops the page clients on reset, and only then', () => {
144
+ const before = createAnalytics({ product: 'site', host: HOST })
145
+ expect(createAnalytics({ product: 'site', host: HOST })).toBe(before)
146
+ resetClients()
147
+ expect(createAnalytics({ product: 'site', host: HOST })).not.toBe(before)
148
+ })
149
+
138
150
  // The package publishes two entries and the react one carries its own copy of
139
151
  // this module, so on a page that imports both there are two module scopes. A
140
152
  // registry held in module scope is per-copy and would not dedupe the only case
package/src/version.ts CHANGED
@@ -1,4 +1,12 @@
1
1
  // The library version, stamped on every event (`libraryVersion`) and on the
2
2
  // Sentry `sdk` block. It lives alone so `sentry.ts` can read it without importing
3
3
  // `core.ts` — core imports sentry, so the reverse would be an import cycle.
4
- export const VERSION = '0.3.37'
4
+ //
5
+ // Read from package.json rather than restated, because a version restated is a
6
+ // version that drifts: 0.3.38 and 0.3.39 both shipped while this file still said
7
+ // 0.3.37, so every event those builds sent named a library that was two releases
8
+ // behind. `resolveJsonModule` inlines the literal at build time, and tsup shakes
9
+ // the rest of the manifest out.
10
+ import { version } from '../package.json'
11
+
12
+ export const VERSION: string = version