@goatech/sdk-js 0.1.0 → 1.0.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 CHANGED
@@ -1,99 +1,37 @@
1
- # @goatech/sdk-js
1
+ # @goatech/sdk-js (deprecated)
2
2
 
3
- Browser-side SDK for the [GoaTech](https://goatech.ai) release-intelligence platform. Ship flags, run experiments, and track events with a tiny (~8KB gzipped) client.
3
+ This package is a backward-compatibility shim. The Sheepit browser SDK has moved to `@sheepit-ai/sdk-js`.
4
4
 
5
- > React apps: use **[@goatech/react](https://www.npmjs.com/package/@goatech/react)** it wraps this SDK with hooks and a provider.
5
+ All exports are identicalonly the package name changed. Swap your dependency:
6
6
 
7
- ## Install
8
-
9
- ```bash
10
- npm install @goatech/sdk-js
11
- # or
12
- pnpm add @goatech/sdk-js
13
- # or
14
- yarn add @goatech/sdk-js
7
+ ```diff
8
+ - "@goatech/sdk-js": "^1.0.0"
9
+ + "@sheepit-ai/sdk-js": "^1.0.0"
15
10
  ```
16
11
 
17
- ## Quickstart
18
-
19
- ```ts
20
- import { GoaTech } from "@goatech/sdk-js";
21
-
22
- const gt = GoaTech.create({
23
- apiKey: "lp_pub_xxx_abc123...", // publishable key — safe in browsers
24
- apiUrl: "https://api.goatech.ai", // optional, defaults to prod
25
- });
26
-
27
- // Track an event
28
- gt.track("course_viewed", { course_id: "abc-123" });
29
-
30
- // Evaluate a flag
31
- const showBeta = gt.flag("show_beta_ui", false);
32
-
33
- // Get an experiment variant (server-bucketed, sticky per device)
34
- const { variant, payload } = gt.experiment("checkout_redesign");
12
+ > **If you're on `^0.1.x`**: this shim publishes as `1.0.0`, so `^0.1.x` will NOT auto-resolve. Change your range to `^1.0.0` (or migrate directly to `@sheepit-ai/sdk-js@^1.0.0`).
35
13
 
36
- // Identify a user after login
37
- gt.identify("user_abc123", { email: "jane@example.com" });
14
+ And update your imports:
38
15
 
39
- // On logout
40
- gt.reset();
16
+ ```diff
17
+ - import { GoaTech } from "@goatech/sdk-js";
18
+ + import { GoaTech } from "@sheepit-ai/sdk-js";
41
19
  ```
42
20
 
43
- ## Keys
44
-
45
- Use the **publishable** key (`lp_pub_*`) in browsers. It can only post events and fetch config — no admin access. Secret keys (`lp_sec_*`) are rejected at initialization if used in a browser context.
46
-
47
- ## API
48
-
49
- ### `GoaTech.create(config)`
50
-
51
- Create an SDK instance. Required: `apiKey`. Other options:
52
-
53
- - `apiUrl` — defaults to `https://api.goatech.ai`
54
- - `debug` — enables verbose logging + local flag overrides
55
- - `flushInterval` — ms between event flushes (default 5000)
56
- - `flushSize` — batch size (default 20)
57
- - `autoCaptureErrors` — capture `window.onerror` + `unhandledrejection` as `$error` events (default `true`; pass `false` to disable or an object to configure)
58
- - `autoCaptureHttpErrors` — wrap `fetch` to emit `$http_error` on non-2xx responses (default `false`)
59
- - `appVersion` — attached to every event for Release attribution
60
-
61
- ### `gt.track(eventName, properties?)`
62
-
63
- Queue an event for batch upload. Returns immediately; events flush on a timer, on `visibilitychange`, and on `pagehide`.
64
-
65
- ### `gt.identify(userId, traits?)`
66
-
67
- Associate the current device with a user. Subsequent events carry `user_id` + `traits`. Do **not** put PII in `traits` unless you've disclosed it.
68
-
69
- ### `gt.reset()`
70
-
71
- Clear user identity and cached experiment assignments. Call on logout.
72
-
73
- ### `gt.flag<T>(flagKey, defaultValue?)`
74
-
75
- Return the server-evaluated flag value, or `defaultValue` if not set. Fires a `$flag_exposure` event once per session per flag.
76
-
77
- ### `gt.experiment(experimentKey)`
78
-
79
- Return the assigned variant for an experiment. Result is `{ variant: string; payload?: Record<string, unknown> }`. Assignments are computed server-side and remain sticky per device.
80
-
81
- ### `gt.flush()`
82
-
83
- Force-flush queued events. Returns a promise that resolves when the batch is sent.
84
-
85
- ### `gt.destroy()`
21
+ The class name `GoaTech` is unchanged — only the package import path moves.
86
22
 
87
- Tear down the instance (stops timers, clears state). Useful in tests.
23
+ This shim will emit a `console.warn` on import until you migrate (once per JS realm — that's once per main thread, once per worker_thread, once per `vm.Context`). It will stop receiving updates after 2026-11-26.
88
24
 
89
- ## Offline
25
+ Full migration guide: https://www.goatech.ai/docs/migrate-to-sheepit
90
26
 
91
- Events queue locally (IndexedDB or localStorage) when the network is down and retry with exponential backoff. Cap is ~1000 events to prevent unbounded memory growth — oldest dropped first.
27
+ ---
92
28
 
93
- ## Type-safe flags via `@goatech/cli`
29
+ ## Publishing this shim (maintainers only)
94
30
 
95
- Install the CLI and run `goatech codegen` to generate type-safe flag constants from your project's Flag definitions. See the [CLI README](https://www.npmjs.com/package/@goatech/cli).
31
+ Order matters. The shim depends on `@sheepit-ai/sdk-js: workspace:*`, which `pnpm publish` rewrites to a real semver range. That rewrite fails closed if the dependency isn't published yet:
96
32
 
97
- ## License
33
+ 1. `pnpm --filter @sheepit-ai/sdk-js publish --access public` — must succeed first.
34
+ 2. `pnpm --filter @goatech/sdk-js publish --access public` — shim publishes after.
35
+ 3. `npm deprecate "@goatech/sdk-js@<2.0.0" "Renamed to @sheepit-ai/sdk-js. See README."`
98
36
 
99
- MIT © GoaTech
37
+ Reversing the order publishes the shim with a broken dep.
@@ -1,39 +1 @@
1
- interface BootErrorScriptOptions {
2
- /**
3
- * URL the ultra-early error script posts to. Must be same-origin relative
4
- * (e.g. "/api/log-boot-error") so `navigator.sendBeacon` works on page unload.
5
- * Customers wire a corresponding server route that forwards to GoaTech or
6
- * logs to their infra. (See README for a Next.js example.)
7
- */
8
- endpoint: string;
9
- /** Stack-trace length cap in chars. Default: 4096. */
10
- stackLimit?: number;
11
- }
12
- /**
13
- * Returns an IIFE string to inline in `<head>` BEFORE any bundle loads.
14
- * Captures errors that happen before React / the SDK hydrates — a render
15
- * crash in that window never reaches the normal event pipeline.
16
- *
17
- * Usage (Next.js App Router):
18
- *
19
- * import { getBootErrorScript } from "@goatech/sdk-js/boot-error";
20
- * ...
21
- * <head>
22
- * <script dangerouslySetInnerHTML={{ __html: getBootErrorScript({ endpoint: "/api/log-boot-error" }) }} />
23
- * </head>
24
- */
25
- declare function getBootErrorScript(options: BootErrorScriptOptions): string;
26
- interface BootErrorPayload {
27
- reason: "uncaught_error" | "unhandled_rejection";
28
- message: string;
29
- source?: string | null;
30
- line?: number | null;
31
- col?: number | null;
32
- stack?: string | null;
33
- ua: string;
34
- url: string;
35
- pathname: string;
36
- ts: number;
37
- }
38
-
39
- export { type BootErrorPayload, type BootErrorScriptOptions, getBootErrorScript };
1
+ export * from '@sheepit-ai/sdk-js/boot-error';
@@ -1,39 +1 @@
1
- interface BootErrorScriptOptions {
2
- /**
3
- * URL the ultra-early error script posts to. Must be same-origin relative
4
- * (e.g. "/api/log-boot-error") so `navigator.sendBeacon` works on page unload.
5
- * Customers wire a corresponding server route that forwards to GoaTech or
6
- * logs to their infra. (See README for a Next.js example.)
7
- */
8
- endpoint: string;
9
- /** Stack-trace length cap in chars. Default: 4096. */
10
- stackLimit?: number;
11
- }
12
- /**
13
- * Returns an IIFE string to inline in `<head>` BEFORE any bundle loads.
14
- * Captures errors that happen before React / the SDK hydrates — a render
15
- * crash in that window never reaches the normal event pipeline.
16
- *
17
- * Usage (Next.js App Router):
18
- *
19
- * import { getBootErrorScript } from "@goatech/sdk-js/boot-error";
20
- * ...
21
- * <head>
22
- * <script dangerouslySetInnerHTML={{ __html: getBootErrorScript({ endpoint: "/api/log-boot-error" }) }} />
23
- * </head>
24
- */
25
- declare function getBootErrorScript(options: BootErrorScriptOptions): string;
26
- interface BootErrorPayload {
27
- reason: "uncaught_error" | "unhandled_rejection";
28
- message: string;
29
- source?: string | null;
30
- line?: number | null;
31
- col?: number | null;
32
- stack?: string | null;
33
- ua: string;
34
- url: string;
35
- pathname: string;
36
- ts: number;
37
- }
38
-
39
- export { type BootErrorPayload, type BootErrorScriptOptions, getBootErrorScript };
1
+ export * from '@sheepit-ai/sdk-js/boot-error';
@@ -1,32 +1,12 @@
1
- 'use strict';function t(e){let n=JSON.stringify(e.endpoint),r=e.stackLimit??4096;return `(function(){
2
- function post(p){
3
- try {
4
- var d = JSON.stringify(p);
5
- if (navigator.sendBeacon) {
6
- navigator.sendBeacon(${n}, new Blob([d],{type:"application/json"}));
7
- } else {
8
- fetch(${n},{method:"POST",body:d,keepalive:true,headers:{"Content-Type":"application/json"}}).catch(function(){});
9
- }
10
- } catch(e){}
11
- }
12
- function base(r){
13
- return {reason:r,ua:navigator.userAgent,url:location.href,ts:Date.now(),pathname:location.pathname};
14
- }
15
- window.addEventListener("error",function(e){
16
- var p=base("uncaught_error");
17
- p.message=e&&e.message?String(e.message):"(no message)";
18
- p.source=e&&e.filename?String(e.filename):null;
19
- p.line=e&&typeof e.lineno==="number"?e.lineno:null;
20
- p.col=e&&typeof e.colno==="number"?e.colno:null;
21
- p.stack=e&&e.error&&e.error.stack?String(e.error.stack).slice(0,${r}):null;
22
- post(p);
23
- });
24
- window.addEventListener("unhandledrejection",function(e){
25
- var p=base("unhandled_rejection");
26
- var r=e&&e.reason;
27
- p.message=r&&r.message?String(r.message):String(r);
28
- p.stack=r&&r.stack?String(r.stack).slice(0,${r}):null;
29
- post(p);
30
- });
31
- })();`}exports.getBootErrorScript=t;//# sourceMappingURL=boot-error.js.map
32
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9ib290LWVycm9yLnRzIl0sIm5hbWVzIjpbImdldEJvb3RFcnJvclNjcmlwdCIsIm9wdGlvbnMiLCJlbmRwb2ludCIsInN0YWNrTGltaXQiXSwibWFwcGluZ3MiOiJhQXlCTyxTQUFTQSxDQUFBQSxDQUFtQkMsQ0FBQUEsQ0FBeUMsQ0FDMUUsSUFBTUMsRUFBVyxJQUFBLENBQUssU0FBQSxDQUFVRCxDQUFBQSxDQUFRLFFBQVEsQ0FBQSxDQUMxQ0UsQ0FBQUEsQ0FBYUYsQ0FBQUEsQ0FBUSxVQUFBLEVBQWMsS0FDekMsT0FBTyxDQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSw2QkFBQSxFQUtzQkMsQ0FBUSxDQUFBO0FBQUE7QUFBQSxjQUFBLEVBRXZCQSxDQUFRLENBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxvRUFBQSxFQWE4Q0MsQ0FBVSxDQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsK0NBQUEsRUFPL0JBLENBQVUsQ0FBQTtBQUFBO0FBQUE7QUFBQSxLQUFBLENBSTNEIiwiZmlsZSI6ImJvb3QtZXJyb3IuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgaW50ZXJmYWNlIEJvb3RFcnJvclNjcmlwdE9wdGlvbnMge1xuICAvKipcbiAgICogVVJMIHRoZSB1bHRyYS1lYXJseSBlcnJvciBzY3JpcHQgcG9zdHMgdG8uIE11c3QgYmUgc2FtZS1vcmlnaW4gcmVsYXRpdmVcbiAgICogKGUuZy4gXCIvYXBpL2xvZy1ib290LWVycm9yXCIpIHNvIGBuYXZpZ2F0b3Iuc2VuZEJlYWNvbmAgd29ya3Mgb24gcGFnZSB1bmxvYWQuXG4gICAqIEN1c3RvbWVycyB3aXJlIGEgY29ycmVzcG9uZGluZyBzZXJ2ZXIgcm91dGUgdGhhdCBmb3J3YXJkcyB0byBHb2FUZWNoIG9yXG4gICAqIGxvZ3MgdG8gdGhlaXIgaW5mcmEuIChTZWUgUkVBRE1FIGZvciBhIE5leHQuanMgZXhhbXBsZS4pXG4gICAqL1xuICBlbmRwb2ludDogc3RyaW5nO1xuICAvKiogU3RhY2stdHJhY2UgbGVuZ3RoIGNhcCBpbiBjaGFycy4gRGVmYXVsdDogNDA5Ni4gKi9cbiAgc3RhY2tMaW1pdD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIElJRkUgc3RyaW5nIHRvIGlubGluZSBpbiBgPGhlYWQ+YCBCRUZPUkUgYW55IGJ1bmRsZSBsb2Fkcy5cbiAqIENhcHR1cmVzIGVycm9ycyB0aGF0IGhhcHBlbiBiZWZvcmUgUmVhY3QgLyB0aGUgU0RLIGh5ZHJhdGVzIOKAlCBhIHJlbmRlclxuICogY3Jhc2ggaW4gdGhhdCB3aW5kb3cgbmV2ZXIgcmVhY2hlcyB0aGUgbm9ybWFsIGV2ZW50IHBpcGVsaW5lLlxuICpcbiAqIFVzYWdlIChOZXh0LmpzIEFwcCBSb3V0ZXIpOlxuICpcbiAqICAgaW1wb3J0IHsgZ2V0Qm9vdEVycm9yU2NyaXB0IH0gZnJvbSBcIkBnb2F0ZWNoL3Nkay1qcy9ib290LWVycm9yXCI7XG4gKiAgIC4uLlxuICogICA8aGVhZD5cbiAqICAgICA8c2NyaXB0IGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MPXt7IF9faHRtbDogZ2V0Qm9vdEVycm9yU2NyaXB0KHsgZW5kcG9pbnQ6IFwiL2FwaS9sb2ctYm9vdC1lcnJvclwiIH0pIH19IC8+XG4gKiAgIDwvaGVhZD5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEJvb3RFcnJvclNjcmlwdChvcHRpb25zOiBCb290RXJyb3JTY3JpcHRPcHRpb25zKTogc3RyaW5nIHtcbiAgY29uc3QgZW5kcG9pbnQgPSBKU09OLnN0cmluZ2lmeShvcHRpb25zLmVuZHBvaW50KTtcbiAgY29uc3Qgc3RhY2tMaW1pdCA9IG9wdGlvbnMuc3RhY2tMaW1pdCA/PyA0MDk2O1xuICByZXR1cm4gYChmdW5jdGlvbigpe1xuICBmdW5jdGlvbiBwb3N0KHApe1xuICAgIHRyeSB7XG4gICAgICB2YXIgZCA9IEpTT04uc3RyaW5naWZ5KHApO1xuICAgICAgaWYgKG5hdmlnYXRvci5zZW5kQmVhY29uKSB7XG4gICAgICAgIG5hdmlnYXRvci5zZW5kQmVhY29uKCR7ZW5kcG9pbnR9LCBuZXcgQmxvYihbZF0se3R5cGU6XCJhcHBsaWNhdGlvbi9qc29uXCJ9KSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmZXRjaCgke2VuZHBvaW50fSx7bWV0aG9kOlwiUE9TVFwiLGJvZHk6ZCxrZWVwYWxpdmU6dHJ1ZSxoZWFkZXJzOntcIkNvbnRlbnQtVHlwZVwiOlwiYXBwbGljYXRpb24vanNvblwifX0pLmNhdGNoKGZ1bmN0aW9uKCl7fSk7XG4gICAgICB9XG4gICAgfSBjYXRjaChlKXt9XG4gIH1cbiAgZnVuY3Rpb24gYmFzZShyKXtcbiAgICByZXR1cm4ge3JlYXNvbjpyLHVhOm5hdmlnYXRvci51c2VyQWdlbnQsdXJsOmxvY2F0aW9uLmhyZWYsdHM6RGF0ZS5ub3coKSxwYXRobmFtZTpsb2NhdGlvbi5wYXRobmFtZX07XG4gIH1cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLGZ1bmN0aW9uKGUpe1xuICAgIHZhciBwPWJhc2UoXCJ1bmNhdWdodF9lcnJvclwiKTtcbiAgICBwLm1lc3NhZ2U9ZSYmZS5tZXNzYWdlP1N0cmluZyhlLm1lc3NhZ2UpOlwiKG5vIG1lc3NhZ2UpXCI7XG4gICAgcC5zb3VyY2U9ZSYmZS5maWxlbmFtZT9TdHJpbmcoZS5maWxlbmFtZSk6bnVsbDtcbiAgICBwLmxpbmU9ZSYmdHlwZW9mIGUubGluZW5vPT09XCJudW1iZXJcIj9lLmxpbmVubzpudWxsO1xuICAgIHAuY29sPWUmJnR5cGVvZiBlLmNvbG5vPT09XCJudW1iZXJcIj9lLmNvbG5vOm51bGw7XG4gICAgcC5zdGFjaz1lJiZlLmVycm9yJiZlLmVycm9yLnN0YWNrP1N0cmluZyhlLmVycm9yLnN0YWNrKS5zbGljZSgwLCR7c3RhY2tMaW1pdH0pOm51bGw7XG4gICAgcG9zdChwKTtcbiAgfSk7XG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwidW5oYW5kbGVkcmVqZWN0aW9uXCIsZnVuY3Rpb24oZSl7XG4gICAgdmFyIHA9YmFzZShcInVuaGFuZGxlZF9yZWplY3Rpb25cIik7XG4gICAgdmFyIHI9ZSYmZS5yZWFzb247XG4gICAgcC5tZXNzYWdlPXImJnIubWVzc2FnZT9TdHJpbmcoci5tZXNzYWdlKTpTdHJpbmcocik7XG4gICAgcC5zdGFjaz1yJiZyLnN0YWNrP1N0cmluZyhyLnN0YWNrKS5zbGljZSgwLCR7c3RhY2tMaW1pdH0pOm51bGw7XG4gICAgcG9zdChwKTtcbiAgfSk7XG59KSgpO2A7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQm9vdEVycm9yUGF5bG9hZCB7XG4gIHJlYXNvbjogXCJ1bmNhdWdodF9lcnJvclwiIHwgXCJ1bmhhbmRsZWRfcmVqZWN0aW9uXCI7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgc291cmNlPzogc3RyaW5nIHwgbnVsbDtcbiAgbGluZT86IG51bWJlciB8IG51bGw7XG4gIGNvbD86IG51bWJlciB8IG51bGw7XG4gIHN0YWNrPzogc3RyaW5nIHwgbnVsbDtcbiAgdWE6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG4gIHBhdGhuYW1lOiBzdHJpbmc7XG4gIHRzOiBudW1iZXI7XG59XG4iXX0=
1
+ 'use strict';
2
+
3
+ var bootError = require('@sheepit-ai/sdk-js/boot-error');
4
+
5
+
6
+
7
+ Object.keys(bootError).forEach(function (k) {
8
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
9
+ enumerable: true,
10
+ get: function () { return bootError[k]; }
11
+ });
12
+ });
@@ -1,2 +1 @@
1
- export{a as getBootErrorScript}from'./chunk-BQTMRKY5.mjs';//# sourceMappingURL=boot-error.mjs.map
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJib290LWVycm9yLm1qcyJ9
1
+ export * from '@sheepit-ai/sdk-js/boot-error';
@@ -1,29 +1 @@
1
- import { s as ExperimentAssignment, E as ExperimentResult } from './types-CxAq_Cds.mjs';
2
- export { j as ExperimentConfig, l as ExperimentVariant } from './types-CxAq_Cds.mjs';
3
-
4
- /**
5
- * Experiments are bucketed server-side. The `/v1/config` endpoint returns
6
- * `experiments: { [experimentKey]: { variant_key, payload } }` — one entry
7
- * per experiment the caller's device is enrolled in. The SDK's job is to
8
- * cache the assignment, emit a single exposure event per session, and
9
- * surface the variant to calling code.
10
- *
11
- * No client-side bucketing. No traffic gates. No cumulative weights. All
12
- * of that happens on the server so every platform (web, iOS, server SDK)
13
- * agrees on the assignment for a given device.
14
- */
15
- declare class ExperimentManager {
16
- private assignments;
17
- /** Persisted per-session: remembers which variant we last surfaced. */
18
- private stickyAssignments;
19
- private exposed;
20
- constructor();
21
- setAssignments(assignments: Record<string, ExperimentAssignment>): void;
22
- count(): number;
23
- resolve(experimentKey: string, onExposure: (key: string, variant: string) => void): ExperimentResult;
24
- clearAssignments(): void;
25
- private loadStickyAssignments;
26
- private saveStickyAssignments;
27
- }
28
-
29
- export { ExperimentManager, ExperimentResult };
1
+ export * from '@sheepit-ai/sdk-js/experiments';
@@ -1,29 +1 @@
1
- import { s as ExperimentAssignment, E as ExperimentResult } from './types-CxAq_Cds.js';
2
- export { j as ExperimentConfig, l as ExperimentVariant } from './types-CxAq_Cds.js';
3
-
4
- /**
5
- * Experiments are bucketed server-side. The `/v1/config` endpoint returns
6
- * `experiments: { [experimentKey]: { variant_key, payload } }` — one entry
7
- * per experiment the caller's device is enrolled in. The SDK's job is to
8
- * cache the assignment, emit a single exposure event per session, and
9
- * surface the variant to calling code.
10
- *
11
- * No client-side bucketing. No traffic gates. No cumulative weights. All
12
- * of that happens on the server so every platform (web, iOS, server SDK)
13
- * agrees on the assignment for a given device.
14
- */
15
- declare class ExperimentManager {
16
- private assignments;
17
- /** Persisted per-session: remembers which variant we last surfaced. */
18
- private stickyAssignments;
19
- private exposed;
20
- constructor();
21
- setAssignments(assignments: Record<string, ExperimentAssignment>): void;
22
- count(): number;
23
- resolve(experimentKey: string, onExposure: (key: string, variant: string) => void): ExperimentResult;
24
- clearAssignments(): void;
25
- private loadStickyAssignments;
26
- private saveStickyAssignments;
27
- }
28
-
29
- export { ExperimentManager, ExperimentResult };
1
+ export * from '@sheepit-ai/sdk-js/experiments';
@@ -1,2 +1,12 @@
1
- 'use strict';var e={deviceId:"gt_device_id",anonymousId:"gt_anonymous_id",identity:"gt_identity",sdkConfig:"gt_config",offlineQueue:"gt_offline_queue",sessionId:"gt_session_id",sessionLastSeen:"gt_session_last_seen",experimentAssignments:"gt_exp_assignments",sessionAttribution:"gt_session_attribution",firstTouchAttribution:"gt_first_touch"};var i=class{constructor(){this.assignments={};this.stickyAssignments={};this.exposed=new Set;this.loadStickyAssignments();}setAssignments(t){this.assignments=t;}count(){return Object.keys(this.assignments).length}resolve(t,r){let n=this.assignments[t];if(!n)return {variant:"control"};let s=n.variant_key;return this.stickyAssignments[t]!==s&&(this.stickyAssignments[t]=s,this.saveStickyAssignments()),this.exposed.has(t)||(this.exposed.add(t),r(t,s)),{variant:s,payload:n.payload}}clearAssignments(){this.stickyAssignments={},this.exposed.clear();try{localStorage.removeItem(e.experimentAssignments);}catch{}}loadStickyAssignments(){try{let t=localStorage.getItem(e.experimentAssignments);t&&(this.stickyAssignments=JSON.parse(t));}catch{this.stickyAssignments={};}}saveStickyAssignments(){try{localStorage.setItem(e.experimentAssignments,JSON.stringify(this.stickyAssignments));}catch{}}};exports.ExperimentManager=i;//# sourceMappingURL=experiments.js.map
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kZWZhdWx0cy50cyIsIi4uL3NyYy9leHBlcmltZW50cy50cyJdLCJuYW1lcyI6WyJTVE9SQUdFX0tFWVMiLCJFeHBlcmltZW50TWFuYWdlciIsImFzc2lnbm1lbnRzIiwiZXhwZXJpbWVudEtleSIsIm9uRXhwb3N1cmUiLCJhc3NpZ25tZW50IiwidmFyaWFudEtleSIsInJhdyJdLCJtYXBwaW5ncyI6ImFBNEJPLElBQU1BLENBQUFBLENBQWUsQ0FDMUIsUUFBQSxDQUFVLGNBQUEsQ0FDVixZQUFhLGlCQUFBLENBQ2IsUUFBQSxDQUFVLGNBQ1YsU0FBQSxDQUFXLFdBQUEsQ0FDWCxhQUFjLGtCQUFBLENBQ2QsU0FBQSxDQUFXLGdCQUNYLGVBQUEsQ0FBaUIsc0JBQUEsQ0FDakIsc0JBQXVCLG9CQUFBLENBSXZCLGtCQUFBLENBQW9CLHlCQUlwQixxQkFBQSxDQUF1QixnQkFDekIsRUM3Qk8sSUFBTUMsRUFBTixLQUF3QixDQU03QixhQUFjLENBTGQsSUFBQSxDQUFRLFlBQW9ELEVBQUMsQ0FFN0QsS0FBUSxpQkFBQSxDQUFxQyxHQUM3QyxJQUFBLENBQVEsT0FBQSxDQUFVLElBQUksR0FBQSxDQUdwQixJQUFBLENBQUssd0JBQ1AsQ0FFQSxlQUFlQyxDQUFBQSxDQUF5RCxDQUN0RSxLQUFLLFdBQUEsQ0FBY0EsRUFDckIsQ0FFQSxLQUFBLEVBQWdCLENBQ2QsT0FBTyxNQUFBLENBQU8sSUFBQSxDQUFLLEtBQUssV0FBVyxDQUFBLENBQUUsTUFDdkMsQ0FFQSxPQUFBLENBQ0VDLEVBQ0FDLENBQUFBLENBQ2tCLENBQ2xCLElBQU1DLENBQUFBLENBQWEsSUFBQSxDQUFLLFlBQVlGLENBQWEsQ0FBQSxDQUNqRCxHQUFJLENBQUNFLENBQUFBLENBQ0gsT0FBTyxDQUFFLE9BQUEsQ0FBUyxTQUFVLENBQUEsQ0FHOUIsSUFBTUMsRUFBYUQsQ0FBQUEsQ0FBVyxXQUFBLENBSTlCLE9BQUksSUFBQSxDQUFLLGlCQUFBLENBQWtCRixDQUFhLElBQU1HLENBQUFBLEdBQzVDLElBQUEsQ0FBSyxrQkFBa0JILENBQWEsQ0FBQSxDQUFJRyxFQUN4QyxJQUFBLENBQUsscUJBQUEsSUFHRixJQUFBLENBQUssT0FBQSxDQUFRLElBQUlILENBQWEsQ0FBQSxHQUNqQyxLQUFLLE9BQUEsQ0FBUSxHQUFBLENBQUlBLENBQWEsQ0FBQSxDQUM5QkMsQ0FBQUEsQ0FBV0QsRUFBZUcsQ0FBVSxDQUFBLENBQUEsQ0FHL0IsQ0FBRSxPQUFBLENBQVNBLENBQUFBLENBQVksUUFBU0QsQ0FBQUEsQ0FBVyxPQUFRLENBQzVELENBRUEsZ0JBQUEsRUFBeUIsQ0FDdkIsSUFBQSxDQUFLLGlCQUFBLENBQW9CLEVBQUMsQ0FDMUIsSUFBQSxDQUFLLFFBQVEsS0FBQSxFQUFNLENBQ25CLEdBQUksQ0FDRixZQUFBLENBQWEsVUFBQSxDQUFXTCxDQUFBQSxDQUFhLHFCQUFxQixFQUM1RCxNQUFRLENBRVIsQ0FDRixDQUVRLHFCQUFBLEVBQThCLENBQ3BDLEdBQUksQ0FDRixJQUFNTyxFQUFNLFlBQUEsQ0FBYSxPQUFBLENBQVFQLEVBQWEscUJBQXFCLENBQUEsQ0FDL0RPLElBQ0YsSUFBQSxDQUFLLGlCQUFBLENBQW9CLEtBQUssS0FBQSxDQUFNQSxDQUFHLEdBRTNDLENBQUEsS0FBUSxDQUNOLEtBQUssaUJBQUEsQ0FBb0IsR0FDM0IsQ0FDRixDQUVRLHVCQUE4QixDQUNwQyxHQUFJLENBQ0YsWUFBQSxDQUFhLE9BQUEsQ0FDWFAsRUFBYSxxQkFBQSxDQUNiLElBQUEsQ0FBSyxVQUFVLElBQUEsQ0FBSyxpQkFBaUIsQ0FDdkMsRUFDRixDQUFBLEtBQVEsQ0FFUixDQUNGLENBQ0YiLCJmaWxlIjoiZXhwZXJpbWVudHMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgU0RLX1ZFUlNJT04gPSBcIjAuMS4wXCI7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUUyA9IHtcbiAgYXBpVXJsOiBcImh0dHBzOi8vYXBpLmdvYXRlY2guYWlcIixcbiAgZW52aXJvbm1lbnQ6IFwicHJvZHVjdGlvblwiLFxuICBmbHVzaEludGVydmFsOiA1MDAwLFxuICBmbHVzaFNpemU6IDIwLFxuICBkZWJ1ZzogZmFsc2UsXG4gIGNvbmZpZ1JlZnJlc2hJbnRlcnZhbDogMzAwXzAwMCxcbiAgbWF4UXVldWVTaXplOiAxMDAwLFxuICByZXRyeUF0dGVtcHRzOiAzLFxuICByZXRyeUJhY2tvZmY6IFsxMDAwLCA1MDAwLCAxNV8wMDBdIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgZGlhZ25vc3RpY0J1ZmZlclNpemU6IDEwMCxcbn0gYXMgY29uc3Q7XG5cbi8qKlxuICogQnJvd3NlciBzdG9yYWdlIGtleXMuXG4gKlxuICogQXVkaXQgRS0wMTAg4oCUIHJlbmFtZWQgZnJvbSBgbHBfKmAgdG8gYGd0XypgIHRvIG1hdGNoIHRoZSByZXN0IG9mIHRoZVxuICogR29hVGVjaCByZW5hbWUuIGBtaWdyYXRlTGVnYWN5U3RvcmFnZUtleXMoKWAgKHNlZSBgLi9zdG9yYWdlLW1pZ3JhdGlvbi50c2ApXG4gKiBydW5zIG9uY2Ugb24gU0RLIGluaXQgYW5kIGNvcGllcyBhbnkgcHJlLWV4aXN0aW5nIGBscF8qYCB2YWx1ZSBpbnRvXG4gKiB0aGUgbmV3IGBndF8qYCBzbG90LCBzbyBleGlzdGluZyB0ZXN0ZXJzIGRvbid0IGxvc2UgdGhlaXIgZGV2aWNlIGlkLFxuICogaWRlbnRpdHksIG9mZmxpbmUgcXVldWUsIGF0dHJpYnV0aW9uLCBvciBleHBlcmltZW50IGFzc2lnbm1lbnRzLlxuICpcbiAqIFNvdXJjZXMgb2YgdHJ1dGg6IG5ldmVyIGhhcmRjb2RlIHRoZSBgZ3RfKmAgc3RyaW5ncyBpbiBjb25zdW1lcnMg4oCUXG4gKiBhbHdheXMgaW1wb3J0IGBTVE9SQUdFX0tFWVMuPG5hbWU+YC4gVGhlIGxlZ2FjeSBzdHJpbmdzIGxpdmUgb25seSBpblxuICogYHN0b3JhZ2UtbWlncmF0aW9uLnRzYC5cbiAqL1xuZXhwb3J0IGNvbnN0IFNUT1JBR0VfS0VZUyA9IHtcbiAgZGV2aWNlSWQ6IFwiZ3RfZGV2aWNlX2lkXCIsXG4gIGFub255bW91c0lkOiBcImd0X2Fub255bW91c19pZFwiLFxuICBpZGVudGl0eTogXCJndF9pZGVudGl0eVwiLFxuICBzZGtDb25maWc6IFwiZ3RfY29uZmlnXCIsXG4gIG9mZmxpbmVRdWV1ZTogXCJndF9vZmZsaW5lX3F1ZXVlXCIsXG4gIHNlc3Npb25JZDogXCJndF9zZXNzaW9uX2lkXCIsXG4gIHNlc3Npb25MYXN0U2VlbjogXCJndF9zZXNzaW9uX2xhc3Rfc2VlblwiLFxuICBleHBlcmltZW50QXNzaWdubWVudHM6IFwiZ3RfZXhwX2Fzc2lnbm1lbnRzXCIsXG4gIC8qKiBQZXItc2Vzc2lvbiBhdHRyaWJ1dGlvbiBzbmFwc2hvdCAoVVRNICsgcmVmZXJyZXIgKyBsYW5kaW5nIHBhZ2UpLlxuICAgKiAgQ2FwdHVyZWQgb24gc2Vzc2lvbiBjcmVhdGlvbjsgcGVyc2lzdHMgZm9yIHRoZSBzZXNzaW9uJ3MgbGlmZXRpbWUgc29cbiAgICogIGV2ZXJ5IGV2ZW50IGluIHRoYXQgc2Vzc2lvbiBjYXJyaWVzIHRoZSBzYW1lIGZpcnN0LXRvdWNoIGNvbnRleHQuICovXG4gIHNlc3Npb25BdHRyaWJ1dGlvbjogXCJndF9zZXNzaW9uX2F0dHJpYnV0aW9uXCIsXG4gIC8qKiBGaXJzdC1ldmVyLXRvdWNoIGF0dHJpYnV0aW9uIGFjcm9zcyB0aGUgd2hvbGUgYnJvd3NlciBsaWZldGltZS5cbiAgICogIFdyaXR0ZW4gb25jZSBvbiB0aGUgZmlyc3Qgc2Vzc2lvbiB3aGVyZSBVVE0gb3IgcmVmZXJyZXIgaXMgcHJlc2VudDtcbiAgICogIG5ldmVyIG92ZXJ3cml0dGVuLiBVc2VmdWwgZm9yIFwiaG93IGRpZCB0aGlzIHVzZXIgRklSU1QgZmluZCB1c1wiLiAqL1xuICBmaXJzdFRvdWNoQXR0cmlidXRpb246IFwiZ3RfZmlyc3RfdG91Y2hcIixcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBTRVNTSU9OX1RJTUVPVVRfTVMgPSAzMCAqIDYwICogMTAwMDtcbmV4cG9ydCBjb25zdCBDT05GSUdfTUFYX0FHRV9NUyA9IDI0ICogNjAgKiA2MCAqIDEwMDA7XG5leHBvcnQgY29uc3QgT0ZGTElORV9RVUVVRV9NQVggPSA1MDA7XG5leHBvcnQgY29uc3QgQVRUUklCVVRFX01BWF9LRVlTID0gNTA7XG5leHBvcnQgY29uc3QgRVZFTlRfTkFNRV9NQVhfTEVOR1RIID0gMjAwO1xuIiwiaW1wb3J0IHsgU1RPUkFHRV9LRVlTIH0gZnJvbSBcIi4vZGVmYXVsdHMuanNcIjtcbmltcG9ydCB0eXBlIHsgRXhwZXJpbWVudEFzc2lnbm1lbnQsIEV4cGVyaW1lbnRSZXN1bHQgfSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuXG50eXBlIEFzc2lnbm1lbnRTdG9yZSA9IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbi8qKlxuICogRXhwZXJpbWVudHMgYXJlIGJ1Y2tldGVkIHNlcnZlci1zaWRlLiBUaGUgYC92MS9jb25maWdgIGVuZHBvaW50IHJldHVybnNcbiAqIGBleHBlcmltZW50czogeyBbZXhwZXJpbWVudEtleV06IHsgdmFyaWFudF9rZXksIHBheWxvYWQgfSB9YCDigJQgb25lIGVudHJ5XG4gKiBwZXIgZXhwZXJpbWVudCB0aGUgY2FsbGVyJ3MgZGV2aWNlIGlzIGVucm9sbGVkIGluLiBUaGUgU0RLJ3Mgam9iIGlzIHRvXG4gKiBjYWNoZSB0aGUgYXNzaWdubWVudCwgZW1pdCBhIHNpbmdsZSBleHBvc3VyZSBldmVudCBwZXIgc2Vzc2lvbiwgYW5kXG4gKiBzdXJmYWNlIHRoZSB2YXJpYW50IHRvIGNhbGxpbmcgY29kZS5cbiAqXG4gKiBObyBjbGllbnQtc2lkZSBidWNrZXRpbmcuIE5vIHRyYWZmaWMgZ2F0ZXMuIE5vIGN1bXVsYXRpdmUgd2VpZ2h0cy4gQWxsXG4gKiBvZiB0aGF0IGhhcHBlbnMgb24gdGhlIHNlcnZlciBzbyBldmVyeSBwbGF0Zm9ybSAod2ViLCBpT1MsIHNlcnZlciBTREspXG4gKiBhZ3JlZXMgb24gdGhlIGFzc2lnbm1lbnQgZm9yIGEgZ2l2ZW4gZGV2aWNlLlxuICovXG5leHBvcnQgY2xhc3MgRXhwZXJpbWVudE1hbmFnZXIge1xuICBwcml2YXRlIGFzc2lnbm1lbnRzOiBSZWNvcmQ8c3RyaW5nLCBFeHBlcmltZW50QXNzaWdubWVudD4gPSB7fTtcbiAgLyoqIFBlcnNpc3RlZCBwZXItc2Vzc2lvbjogcmVtZW1iZXJzIHdoaWNoIHZhcmlhbnQgd2UgbGFzdCBzdXJmYWNlZC4gKi9cbiAgcHJpdmF0ZSBzdGlja3lBc3NpZ25tZW50czogQXNzaWdubWVudFN0b3JlID0ge307XG4gIHByaXZhdGUgZXhwb3NlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMubG9hZFN0aWNreUFzc2lnbm1lbnRzKCk7XG4gIH1cblxuICBzZXRBc3NpZ25tZW50cyhhc3NpZ25tZW50czogUmVjb3JkPHN0cmluZywgRXhwZXJpbWVudEFzc2lnbm1lbnQ+KTogdm9pZCB7XG4gICAgdGhpcy5hc3NpZ25tZW50cyA9IGFzc2lnbm1lbnRzO1xuICB9XG5cbiAgY291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5hc3NpZ25tZW50cykubGVuZ3RoO1xuICB9XG5cbiAgcmVzb2x2ZShcbiAgICBleHBlcmltZW50S2V5OiBzdHJpbmcsXG4gICAgb25FeHBvc3VyZTogKGtleTogc3RyaW5nLCB2YXJpYW50OiBzdHJpbmcpID0+IHZvaWQsXG4gICk6IEV4cGVyaW1lbnRSZXN1bHQge1xuICAgIGNvbnN0IGFzc2lnbm1lbnQgPSB0aGlzLmFzc2lnbm1lbnRzW2V4cGVyaW1lbnRLZXldO1xuICAgIGlmICghYXNzaWdubWVudCkge1xuICAgICAgcmV0dXJuIHsgdmFyaWFudDogXCJjb250cm9sXCIgfTtcbiAgICB9XG5cbiAgICBjb25zdCB2YXJpYW50S2V5ID0gYXNzaWdubWVudC52YXJpYW50X2tleTtcblxuICAgIC8vIFBlcnNpc3Qgc28gdGhlIHZhcmlhbnQgaXMgc3RhYmxlIGV2ZW4gaWYgdGhlIHNlcnZlciByZXNwb25zZSBpc1xuICAgIC8vIGJyaWVmbHkgdW5hdmFpbGFibGUgYWZ0ZXIgYSBjYWNoZSBtaXNzLlxuICAgIGlmICh0aGlzLnN0aWNreUFzc2lnbm1lbnRzW2V4cGVyaW1lbnRLZXldICE9PSB2YXJpYW50S2V5KSB7XG4gICAgICB0aGlzLnN0aWNreUFzc2lnbm1lbnRzW2V4cGVyaW1lbnRLZXldID0gdmFyaWFudEtleTtcbiAgICAgIHRoaXMuc2F2ZVN0aWNreUFzc2lnbm1lbnRzKCk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmV4cG9zZWQuaGFzKGV4cGVyaW1lbnRLZXkpKSB7XG4gICAgICB0aGlzLmV4cG9zZWQuYWRkKGV4cGVyaW1lbnRLZXkpO1xuICAgICAgb25FeHBvc3VyZShleHBlcmltZW50S2V5LCB2YXJpYW50S2V5KTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB2YXJpYW50OiB2YXJpYW50S2V5LCBwYXlsb2FkOiBhc3NpZ25tZW50LnBheWxvYWQgfTtcbiAgfVxuXG4gIGNsZWFyQXNzaWdubWVudHMoKTogdm9pZCB7XG4gICAgdGhpcy5zdGlja3lBc3NpZ25tZW50cyA9IHt9O1xuICAgIHRoaXMuZXhwb3NlZC5jbGVhcigpO1xuICAgIHRyeSB7XG4gICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShTVE9SQUdFX0tFWVMuZXhwZXJpbWVudEFzc2lnbm1lbnRzKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIG5vIGxvY2FsU3RvcmFnZVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbG9hZFN0aWNreUFzc2lnbm1lbnRzKCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByYXcgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShTVE9SQUdFX0tFWVMuZXhwZXJpbWVudEFzc2lnbm1lbnRzKTtcbiAgICAgIGlmIChyYXcpIHtcbiAgICAgICAgdGhpcy5zdGlja3lBc3NpZ25tZW50cyA9IEpTT04ucGFyc2UocmF3KSBhcyBBc3NpZ25tZW50U3RvcmU7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICB0aGlzLnN0aWNreUFzc2lnbm1lbnRzID0ge307XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzYXZlU3RpY2t5QXNzaWdubWVudHMoKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFxuICAgICAgICBTVE9SQUdFX0tFWVMuZXhwZXJpbWVudEFzc2lnbm1lbnRzLFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLnN0aWNreUFzc2lnbm1lbnRzKSxcbiAgICAgICk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBubyBsb2NhbFN0b3JhZ2VcbiAgICB9XG4gIH1cbn1cbiJdfQ==
1
+ 'use strict';
2
+
3
+ var experiments = require('@sheepit-ai/sdk-js/experiments');
4
+
5
+
6
+
7
+ Object.keys(experiments).forEach(function (k) {
8
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
9
+ enumerable: true,
10
+ get: function () { return experiments[k]; }
11
+ });
12
+ });
@@ -1,2 +1 @@
1
- export{h as ExperimentManager}from'./chunk-X5MDWZGR.mjs';//# sourceMappingURL=experiments.mjs.map
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJleHBlcmltZW50cy5tanMifQ==
1
+ export * from '@sheepit-ai/sdk-js/experiments';
package/dist/flags.d.mts CHANGED
@@ -1,34 +1 @@
1
- import { F as FlagValue } from './types-CxAq_Cds.mjs';
2
- export { C as Condition, m as FlagConfig, n as FlagRule } from './types-CxAq_Cds.mjs';
3
-
4
- /**
5
- * FlagManager stores server-evaluated Flag values and exposes them to SDK
6
- * consumers. Evaluation happens on the API (see `/v1/config`); the SDK only
7
- * caches the result and tracks exposure once per flag per session.
8
- *
9
- * Debug overrides take precedence over server values when debug mode is
10
- * active, so developers can test different branches without touching the
11
- * server. Overrides are persisted in localStorage under DEBUG_OVERRIDES_KEY.
12
- */
13
- declare class FlagManager {
14
- private flagValues;
15
- private debugOverrides;
16
- private exposed;
17
- private debugMode;
18
- /** Apply the latest evaluated flag values from `/v1/config`. */
19
- setEvaluatedFlags(flags: Record<string, unknown>): void;
20
- setDebugMode(enabled: boolean): void;
21
- /** Override a flag value for local testing. Only active when debug=true. */
22
- overrideFlag(key: string, value: FlagValue): void;
23
- /** Clear all debug overrides. */
24
- clearOverrides(): void;
25
- /** Get all current debug overrides (for debug menu UI). */
26
- getOverrides(): Record<string, unknown>;
27
- count(): number;
28
- evaluate(flagKey: string, defaultValue: FlagValue, _userId: string | null, _attributes: Record<string, unknown>, onExposure: (flagKey: string, value: FlagValue) => void): FlagValue;
29
- clearExposed(): void;
30
- private loadDebugOverrides;
31
- private saveDebugOverrides;
32
- }
33
-
34
- export { FlagManager, FlagValue };
1
+ export * from '@sheepit-ai/sdk-js/flags';
package/dist/flags.d.ts CHANGED
@@ -1,34 +1 @@
1
- import { F as FlagValue } from './types-CxAq_Cds.js';
2
- export { C as Condition, m as FlagConfig, n as FlagRule } from './types-CxAq_Cds.js';
3
-
4
- /**
5
- * FlagManager stores server-evaluated Flag values and exposes them to SDK
6
- * consumers. Evaluation happens on the API (see `/v1/config`); the SDK only
7
- * caches the result and tracks exposure once per flag per session.
8
- *
9
- * Debug overrides take precedence over server values when debug mode is
10
- * active, so developers can test different branches without touching the
11
- * server. Overrides are persisted in localStorage under DEBUG_OVERRIDES_KEY.
12
- */
13
- declare class FlagManager {
14
- private flagValues;
15
- private debugOverrides;
16
- private exposed;
17
- private debugMode;
18
- /** Apply the latest evaluated flag values from `/v1/config`. */
19
- setEvaluatedFlags(flags: Record<string, unknown>): void;
20
- setDebugMode(enabled: boolean): void;
21
- /** Override a flag value for local testing. Only active when debug=true. */
22
- overrideFlag(key: string, value: FlagValue): void;
23
- /** Clear all debug overrides. */
24
- clearOverrides(): void;
25
- /** Get all current debug overrides (for debug menu UI). */
26
- getOverrides(): Record<string, unknown>;
27
- count(): number;
28
- evaluate(flagKey: string, defaultValue: FlagValue, _userId: string | null, _attributes: Record<string, unknown>, onExposure: (flagKey: string, value: FlagValue) => void): FlagValue;
29
- clearExposed(): void;
30
- private loadDebugOverrides;
31
- private saveDebugOverrides;
32
- }
33
-
34
- export { FlagManager, FlagValue };
1
+ export * from '@sheepit-ai/sdk-js/flags';
package/dist/flags.js CHANGED
@@ -1,2 +1,12 @@
1
- 'use strict';var s="lp_debug_overrides",t=class{constructor(){this.flagValues={};this.debugOverrides={};this.exposed=new Set;this.debugMode=false;}setEvaluatedFlags(e){this.flagValues=e,this.exposed.clear();}setDebugMode(e){this.debugMode=e,e&&this.loadDebugOverrides();}overrideFlag(e,r){this.debugOverrides[e]=r,this.saveDebugOverrides();}clearOverrides(){this.debugOverrides={};try{localStorage.removeItem(s);}catch{}}getOverrides(){return {...this.debugOverrides}}count(){return Object.keys(this.flagValues).length}evaluate(e,r,o,u,a){if(this.debugMode&&e in this.debugOverrides)return this.debugOverrides[e];if(e in this.flagValues){let i=this.flagValues[e];return this.exposed.has(e)||(this.exposed.add(e),a(e,i)),i}return r}clearExposed(){this.exposed.clear();}loadDebugOverrides(){try{let e=localStorage.getItem(s);e&&(this.debugOverrides=JSON.parse(e));}catch{}}saveDebugOverrides(){try{localStorage.setItem(s,JSON.stringify(this.debugOverrides));}catch{}}};exports.FlagManager=t;//# sourceMappingURL=flags.js.map
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9mbGFncy50cyJdLCJuYW1lcyI6WyJERUJVR19PVkVSUklERVNfS0VZIiwiRmxhZ01hbmFnZXIiLCJmbGFncyIsImVuYWJsZWQiLCJrZXkiLCJ2YWx1ZSIsImZsYWdLZXkiLCJkZWZhdWx0VmFsdWUiLCJfdXNlcklkIiwiX2F0dHJpYnV0ZXMiLCJvbkV4cG9zdXJlIiwic3RvcmVkIl0sIm1hcHBpbmdzIjoiYUFFQSxJQUFNQSxFQUFzQixvQkFBQSxDQVdmQyxDQUFBQSxDQUFOLEtBQWtCLENBQWxCLFdBQUEsRUFBQSxDQUNMLEtBQVEsVUFBQSxDQUFzQyxHQUM5QyxJQUFBLENBQVEsY0FBQSxDQUEwQyxFQUFDLENBQ25ELElBQUEsQ0FBUSxRQUFVLElBQUksR0FBQSxDQUN0QixLQUFRLFNBQUEsQ0FBWSxNQUFBLENBR3BCLGtCQUFrQkMsQ0FBQUEsQ0FBc0MsQ0FDdEQsS0FBSyxVQUFBLENBQWFBLENBQUFBLENBQ2xCLEtBQUssT0FBQSxDQUFRLEtBQUEsR0FDZixDQUVBLFlBQUEsQ0FBYUMsRUFBd0IsQ0FDbkMsSUFBQSxDQUFLLFVBQVlBLENBQUFBLENBQ2JBLENBQUFBLEVBQVMsS0FBSyxrQkFBQSxHQUNwQixDQUdBLFlBQUEsQ0FBYUMsQ0FBQUEsQ0FBYUMsQ0FBQUEsQ0FBd0IsQ0FDaEQsS0FBSyxjQUFBLENBQWVELENBQUcsRUFBSUMsQ0FBQUEsQ0FDM0IsSUFBQSxDQUFLLHFCQUNQLENBR0EsZ0JBQXVCLENBQ3JCLElBQUEsQ0FBSyxlQUFpQixFQUFDLENBQ3ZCLEdBQUksQ0FDRixZQUFBLENBQWEsV0FBV0wsQ0FBbUIsRUFDN0MsTUFBUSxDQUVSLENBQ0YsQ0FHQSxZQUFBLEVBQXdDLENBQ3RDLE9BQU8sQ0FBRSxHQUFHLEtBQUssY0FBZSxDQUNsQyxDQUVBLEtBQUEsRUFBZ0IsQ0FDZCxPQUFPLE1BQUEsQ0FBTyxJQUFBLENBQUssS0FBSyxVQUFVLENBQUEsQ0FBRSxNQUN0QyxDQUVBLFFBQUEsQ0FDRU0sQ0FBQUEsQ0FDQUMsQ0FBQUEsQ0FDQUMsRUFDQUMsQ0FBQUEsQ0FDQUMsQ0FBQUEsQ0FDVyxDQUNYLEdBQUksSUFBQSxDQUFLLFdBQWFKLENBQUFBLElBQVcsSUFBQSxDQUFLLGVBQ3BDLE9BQU8sSUFBQSxDQUFLLGVBQWVBLENBQU8sQ0FBQSxDQUdwQyxHQUFJQSxDQUFBQSxJQUFXLElBQUEsQ0FBSyxXQUFZLENBQzlCLElBQU1ELEVBQVEsSUFBQSxDQUFLLFVBQUEsQ0FBV0MsQ0FBTyxDQUFBLENBQ3JDLE9BQUssS0FBSyxPQUFBLENBQVEsR0FBQSxDQUFJQSxDQUFPLENBQUEsR0FDM0IsSUFBQSxDQUFLLFFBQVEsR0FBQSxDQUFJQSxDQUFPLEVBQ3hCSSxDQUFBQSxDQUFXSixDQUFBQSxDQUFTRCxDQUFLLENBQUEsQ0FBQSxDQUVwQkEsQ0FDVCxDQUVBLE9BQU9FLENBQ1QsQ0FFQSxZQUFBLEVBQXFCLENBQ25CLElBQUEsQ0FBSyxPQUFBLENBQVEsUUFDZixDQUVRLG9CQUEyQixDQUNqQyxHQUFJLENBQ0YsSUFBTUksQ0FBQUEsQ0FBUyxhQUFhLE9BQUEsQ0FBUVgsQ0FBbUIsRUFDbkRXLENBQUFBLEdBQVEsSUFBQSxDQUFLLGVBQWlCLElBQUEsQ0FBSyxLQUFBLENBQU1BLENBQU0sQ0FBQSxFQUNyRCxDQUFBLEtBQVEsQ0FFUixDQUNGLENBRVEsb0JBQTJCLENBQ2pDLEdBQUksQ0FDRixZQUFBLENBQWEsT0FBQSxDQUFRWCxFQUFxQixJQUFBLENBQUssU0FBQSxDQUFVLEtBQUssY0FBYyxDQUFDLEVBQy9FLENBQUEsS0FBUSxDQUVSLENBQ0YsQ0FDRiIsImZpbGUiOiJmbGFncy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRmxhZ1ZhbHVlIH0gZnJvbSBcIi4vdHlwZXMuanNcIjtcblxuY29uc3QgREVCVUdfT1ZFUlJJREVTX0tFWSA9IFwibHBfZGVidWdfb3ZlcnJpZGVzXCI7XG5cbi8qKlxuICogRmxhZ01hbmFnZXIgc3RvcmVzIHNlcnZlci1ldmFsdWF0ZWQgRmxhZyB2YWx1ZXMgYW5kIGV4cG9zZXMgdGhlbSB0byBTREtcbiAqIGNvbnN1bWVycy4gRXZhbHVhdGlvbiBoYXBwZW5zIG9uIHRoZSBBUEkgKHNlZSBgL3YxL2NvbmZpZ2ApOyB0aGUgU0RLIG9ubHlcbiAqIGNhY2hlcyB0aGUgcmVzdWx0IGFuZCB0cmFja3MgZXhwb3N1cmUgb25jZSBwZXIgZmxhZyBwZXIgc2Vzc2lvbi5cbiAqXG4gKiBEZWJ1ZyBvdmVycmlkZXMgdGFrZSBwcmVjZWRlbmNlIG92ZXIgc2VydmVyIHZhbHVlcyB3aGVuIGRlYnVnIG1vZGUgaXNcbiAqIGFjdGl2ZSwgc28gZGV2ZWxvcGVycyBjYW4gdGVzdCBkaWZmZXJlbnQgYnJhbmNoZXMgd2l0aG91dCB0b3VjaGluZyB0aGVcbiAqIHNlcnZlci4gT3ZlcnJpZGVzIGFyZSBwZXJzaXN0ZWQgaW4gbG9jYWxTdG9yYWdlIHVuZGVyIERFQlVHX09WRVJSSURFU19LRVkuXG4gKi9cbmV4cG9ydCBjbGFzcyBGbGFnTWFuYWdlciB7XG4gIHByaXZhdGUgZmxhZ1ZhbHVlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgcHJpdmF0ZSBkZWJ1Z092ZXJyaWRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgcHJpdmF0ZSBleHBvc2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIHByaXZhdGUgZGVidWdNb2RlID0gZmFsc2U7XG5cbiAgLyoqIEFwcGx5IHRoZSBsYXRlc3QgZXZhbHVhdGVkIGZsYWcgdmFsdWVzIGZyb20gYC92MS9jb25maWdgLiAqL1xuICBzZXRFdmFsdWF0ZWRGbGFncyhmbGFnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiB2b2lkIHtcbiAgICB0aGlzLmZsYWdWYWx1ZXMgPSBmbGFncztcbiAgICB0aGlzLmV4cG9zZWQuY2xlYXIoKTtcbiAgfVxuXG4gIHNldERlYnVnTW9kZShlbmFibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5kZWJ1Z01vZGUgPSBlbmFibGVkO1xuICAgIGlmIChlbmFibGVkKSB0aGlzLmxvYWREZWJ1Z092ZXJyaWRlcygpO1xuICB9XG5cbiAgLyoqIE92ZXJyaWRlIGEgZmxhZyB2YWx1ZSBmb3IgbG9jYWwgdGVzdGluZy4gT25seSBhY3RpdmUgd2hlbiBkZWJ1Zz10cnVlLiAqL1xuICBvdmVycmlkZUZsYWcoa2V5OiBzdHJpbmcsIHZhbHVlOiBGbGFnVmFsdWUpOiB2b2lkIHtcbiAgICB0aGlzLmRlYnVnT3ZlcnJpZGVzW2tleV0gPSB2YWx1ZTtcbiAgICB0aGlzLnNhdmVEZWJ1Z092ZXJyaWRlcygpO1xuICB9XG5cbiAgLyoqIENsZWFyIGFsbCBkZWJ1ZyBvdmVycmlkZXMuICovXG4gIGNsZWFyT3ZlcnJpZGVzKCk6IHZvaWQge1xuICAgIHRoaXMuZGVidWdPdmVycmlkZXMgPSB7fTtcbiAgICB0cnkge1xuICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oREVCVUdfT1ZFUlJJREVTX0tFWSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBubyBsb2NhbFN0b3JhZ2VcbiAgICB9XG4gIH1cblxuICAvKiogR2V0IGFsbCBjdXJyZW50IGRlYnVnIG92ZXJyaWRlcyAoZm9yIGRlYnVnIG1lbnUgVUkpLiAqL1xuICBnZXRPdmVycmlkZXMoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIHJldHVybiB7IC4uLnRoaXMuZGVidWdPdmVycmlkZXMgfTtcbiAgfVxuXG4gIGNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZmxhZ1ZhbHVlcykubGVuZ3RoO1xuICB9XG5cbiAgZXZhbHVhdGUoXG4gICAgZmxhZ0tleTogc3RyaW5nLFxuICAgIGRlZmF1bHRWYWx1ZTogRmxhZ1ZhbHVlLFxuICAgIF91c2VySWQ6IHN0cmluZyB8IG51bGwsXG4gICAgX2F0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgIG9uRXhwb3N1cmU6IChmbGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBGbGFnVmFsdWUpID0+IHZvaWQsXG4gICk6IEZsYWdWYWx1ZSB7XG4gICAgaWYgKHRoaXMuZGVidWdNb2RlICYmIGZsYWdLZXkgaW4gdGhpcy5kZWJ1Z092ZXJyaWRlcykge1xuICAgICAgcmV0dXJuIHRoaXMuZGVidWdPdmVycmlkZXNbZmxhZ0tleV0gYXMgRmxhZ1ZhbHVlO1xuICAgIH1cblxuICAgIGlmIChmbGFnS2V5IGluIHRoaXMuZmxhZ1ZhbHVlcykge1xuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmZsYWdWYWx1ZXNbZmxhZ0tleV0gYXMgRmxhZ1ZhbHVlO1xuICAgICAgaWYgKCF0aGlzLmV4cG9zZWQuaGFzKGZsYWdLZXkpKSB7XG4gICAgICAgIHRoaXMuZXhwb3NlZC5hZGQoZmxhZ0tleSk7XG4gICAgICAgIG9uRXhwb3N1cmUoZmxhZ0tleSwgdmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gIH1cblxuICBjbGVhckV4cG9zZWQoKTogdm9pZCB7XG4gICAgdGhpcy5leHBvc2VkLmNsZWFyKCk7XG4gIH1cblxuICBwcml2YXRlIGxvYWREZWJ1Z092ZXJyaWRlcygpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3RvcmVkID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oREVCVUdfT1ZFUlJJREVTX0tFWSk7XG4gICAgICBpZiAoc3RvcmVkKSB0aGlzLmRlYnVnT3ZlcnJpZGVzID0gSlNPTi5wYXJzZShzdG9yZWQpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gbm8gbG9jYWxTdG9yYWdlIG9yIGludmFsaWQgSlNPTlxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2F2ZURlYnVnT3ZlcnJpZGVzKCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShERUJVR19PVkVSUklERVNfS0VZLCBKU09OLnN0cmluZ2lmeSh0aGlzLmRlYnVnT3ZlcnJpZGVzKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBubyBsb2NhbFN0b3JhZ2VcbiAgICB9XG4gIH1cbn1cbiJdfQ==
1
+ 'use strict';
2
+
3
+ var flags = require('@sheepit-ai/sdk-js/flags');
4
+
5
+
6
+
7
+ Object.keys(flags).forEach(function (k) {
8
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
9
+ enumerable: true,
10
+ get: function () { return flags[k]; }
11
+ });
12
+ });
package/dist/flags.mjs CHANGED
@@ -1,2 +1 @@
1
- export{a as FlagManager}from'./chunk-6BNLBHZS.mjs';//# sourceMappingURL=flags.mjs.map
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJmbGFncy5tanMifQ==
1
+ export * from '@sheepit-ai/sdk-js/flags';
package/dist/index.d.mts CHANGED
@@ -1,170 +1,4 @@
1
- import { F as FlagValue, E as ExperimentResult, S as SDKStatus, D as DiagnosticBus, a as DiagnosticEvent, G as GoaTechConfig } from './types-CxAq_Cds.mjs';
2
- export { B as BrowserErrorCapture, C as Condition, b as ConditionOp, c as DeviceInfo, d as DiagnosticCategory, e as DiagnosticListener, f as DiagnosticSeverity, g as EnrichedEvent, h as ErrorCaptureConfig, i as EventContext, j as ExperimentConfig, k as ExperimentStatus, l as ExperimentVariant, m as FlagConfig, n as FlagRule, H as HttpErrorCapture, o as HttpErrorCaptureConfig, p as HttpErrorEventDetail, q as SDKConfig, r as SubscribeOptions } from './types-CxAq_Cds.mjs';
3
- export { BootErrorPayload, BootErrorScriptOptions, getBootErrorScript } from './boot-error.mjs';
4
-
5
- /**
6
- * Public API surface of a GoaTech client instance.
7
- * Use this type when you need to pass around a client reference
8
- * without depending on the concrete GoaTech class.
9
- */
10
- interface IGoaTech {
11
- track(eventName: string, properties?: Record<string, unknown>): void;
12
- identify(userId: string, traits?: Record<string, unknown>): void;
13
- reset(): void;
14
- flag(flagKey: string, defaultValue?: FlagValue): FlagValue;
15
- experiment(experimentKey: string): ExperimentResult;
16
- /** Override a flag value for local testing. Only active when debug=true. */
17
- overrideFlag(key: string, value: FlagValue): void;
18
- /** Clear all debug overrides. */
19
- clearOverrides(): void;
20
- /** Get all current debug overrides (for debug menu UI). */
21
- getOverrides(): Record<string, unknown>;
22
- flush(): Promise<void>;
23
- /** Notify the SDK of a route change in a single-page app. Emits a
24
- * synthetic `$page_leave` for the prior route (if any) and resets
25
- * the page-leave timer for the new path. */
26
- recordPageView(path: string): void;
27
- status(): SDKStatus;
28
- destroy(): void;
29
- /** Access the diagnostic event bus for runtime subscribe/unsubscribe. */
30
- diagnostics(): DiagnosticBus;
31
- /** Get buffered recent diagnostic events. */
32
- getRecentDiagnostics(): DiagnosticEvent[];
33
- }
34
-
35
- declare class GoaTech implements IGoaTech {
36
- private static instance;
37
- private readonly cfg;
38
- private readonly log;
39
- private readonly bus;
40
- private readonly context;
41
- private readonly queue;
42
- private readonly flagManager;
43
- private readonly experimentManager;
44
- private readonly identityManager;
45
- private readonly configSync;
46
- private readonly transport;
47
- private readonly offlineQueue;
48
- private readonly connectivity;
49
- private readonly lifecycle;
50
- private readonly errorCapture;
51
- private readonly httpErrorCapture;
52
- private readonly clickFrustrationCapture;
53
- private flushTimer;
54
- private destroyed;
55
- private constructor();
56
- /**
57
- * Create a new, independent GoaTech instance.
58
- * The caller owns the instance lifecycle — no global state.
59
- * Preferred for React apps (pass instance to Context).
60
- */
61
- static create(config: GoaTechConfig): GoaTech;
62
- /**
63
- * Create a singleton instance. Returns existing instance if already
64
- * initialized (logs a warning). Call `destroy()` first to re-initialize.
65
- *
66
- * For React apps, prefer `GoaTech.create()` + Context instead.
67
- */
68
- static init(config: GoaTechConfig): GoaTech;
69
- /** Get the singleton instance. Throws if `init()` was never called. */
70
- static getInstance(): GoaTech;
71
- /**
72
- * Returns true if the singleton has been initialized via `init()`.
73
- * Useful for HMR guards and conditional initialization.
74
- */
75
- static isInitialized(): boolean;
76
- /**
77
- * Queue an analytics event. Auto-flushes when the queue reaches
78
- * `flushSize` (default 20) or when the periodic flush timer fires.
79
- *
80
- * @example
81
- * gt.track("course_viewed", { course_id: "c_123", source: "catalog" });
82
- */
83
- track(eventName: string, properties?: Record<string, unknown>): void;
84
- /**
85
- * Resolve a feature flag for the current device + identity. Reads
86
- * the cached server-evaluated value from `/v1/config` (refreshed on
87
- * `configRefreshInterval`). Fires `$flag_exposure` once per session
88
- * per flag.
89
- *
90
- * @example
91
- * if (gt.flag("new_checkout_flow", false)) {
92
- * renderNewCheckout();
93
- * }
94
- */
95
- flag(flagKey: string, defaultValue?: FlagValue): FlagValue;
96
- overrideFlag(key: string, value: FlagValue): void;
97
- clearOverrides(): void;
98
- getOverrides(): Record<string, unknown>;
99
- /**
100
- * Resolve the bucketed variant + payload for an experiment. Sticky
101
- * per device. Fires `$experiment_exposure` once per session per
102
- * experiment.
103
- *
104
- * @example
105
- * const { variant, payload } = gt.experiment("hero_h1_copy_v1");
106
- * if (variant !== "control") setHeadline((payload as { headline: string }).headline);
107
- */
108
- experiment(experimentKey: string): ExperimentResult;
109
- /**
110
- * Tie the current device to a stable user id and merge traits onto
111
- * the GoaTech user record. Re-identifying with a different userId
112
- * clears the cached experiment assignments so the new identity
113
- * gets fresh buckets.
114
- *
115
- * @example
116
- * await api.login(form);
117
- * gt.identify("user_abc123", { email: "jane@example.com", plan: "pro" });
118
- */
119
- identify(userId: string, traits?: Record<string, unknown>): void;
120
- /**
121
- * Forget the current identity + experiment assignments and start a
122
- * fresh anonymous session. Call on logout.
123
- *
124
- * @example
125
- * await api.logout();
126
- * gt.reset();
127
- */
128
- reset(): void;
129
- /**
130
- * Drain any queued events to the GoaTech ingest endpoint. Useful
131
- * before navigation in single-page apps and required before
132
- * Vercel/Lambda function exits.
133
- *
134
- * @example
135
- * router.beforeEach(async () => {
136
- * await gt.flush();
137
- * });
138
- */
139
- flush(): Promise<void>;
140
- /**
141
- * Notify the SDK of a route change. The first call starts a page-leave
142
- * timer; subsequent calls emit a synthetic `$page_leave` for the prior
143
- * route (with `exit_kind: "spa_nav"`) before resetting state. Wire
144
- * this into your router — for Next.js, use `<PageViewTracker>` from
145
- * `@goatech/react`, which calls this for you.
146
- *
147
- * Idempotent for repeat calls with the same path.
148
- */
149
- recordPageView(path: string): void;
150
- status(): SDKStatus;
151
- diagnostics(): DiagnosticBus;
152
- getRecentDiagnostics(): DiagnosticEvent[];
153
- /**
154
- * Stop all timers, drain remaining events, and tear down auto-error
155
- * + lifecycle listeners. After `destroy()` further `track()` /
156
- * `flag()` calls are no-ops. Idempotent.
157
- *
158
- * @example
159
- * // Replacing the SDK instance (rare; usually just call once)
160
- * const old = GoaTech.getInstance();
161
- * old.destroy();
162
- * const fresh = GoaTech.init({ apiKey: nextKey });
163
- */
164
- destroy(): void;
165
- private start;
166
- private applyConfig;
167
- private postIdentityResolve;
168
- }
169
-
170
- export { DiagnosticBus, DiagnosticEvent, ExperimentResult, FlagValue, GoaTech, GoaTechConfig, type IGoaTech, SDKStatus };
1
+ export * from '@sheepit-ai/sdk-js';
2
+ import '@sheepit-ai/sdk-js/boot-error';
3
+ import '@sheepit-ai/sdk-js/flags';
4
+ import '@sheepit-ai/sdk-js/experiments';