sdk-garden-js 0.1.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 +54 -23
- package/dist/index.d.mts +72 -21
- package/dist/index.d.ts +72 -21
- package/dist/index.js +699 -141
- package/dist/index.mjs +698 -141
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -32,6 +32,8 @@ class PaymentsSDK {
|
|
|
32
32
|
export const trackedProcess = SdkGarden.trackMethod('processPayment', processPayment);
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
Both forms can run before `init()`, for example at module level: calls pass straight through until `init()` runs and are recorded from then on.
|
|
36
|
+
|
|
35
37
|
**CommonJS (Node.js / require):**
|
|
36
38
|
|
|
37
39
|
```javascript
|
|
@@ -44,6 +46,8 @@ SdkGarden.init({
|
|
|
44
46
|
});
|
|
45
47
|
```
|
|
46
48
|
|
|
49
|
+
Requires Node.js 18+ (for the global `fetch`) or any modern browser.
|
|
50
|
+
|
|
47
51
|
## Configuration
|
|
48
52
|
|
|
49
53
|
| Parameter | Type | Default | Description |
|
|
@@ -51,55 +55,82 @@ SdkGarden.init({
|
|
|
51
55
|
| `apiKey` | `string` | _(required)_ | Your SDK Garden API key (starts with `sgk_`) |
|
|
52
56
|
| `sdkName` | `string` | _(required)_ | The name of your SDK (e.g. `"my-payments-sdk"`) |
|
|
53
57
|
| `sdkVersion` | `string` | _(required)_ | The version of your SDK (e.g. `"1.2.3"`) |
|
|
54
|
-
| `endpoint` | `string` | `"https://ingest.sdkgarden.
|
|
58
|
+
| `endpoint` | `string` | `"https://ingest.sdkgarden.com/track"` | Override the ingest endpoint (for self-hosted SDK Garden, `https://<your-host>/track`) |
|
|
55
59
|
| `debug` | `boolean` | `false` | Enable debug logging to console |
|
|
56
60
|
| `disabled` | `boolean` | `false` | When `true`, all methods become no-ops |
|
|
57
|
-
| `batchSize` | `number` | `10` | Maximum events per
|
|
58
|
-
| `flushInterval` | `number` | `5000` |
|
|
61
|
+
| `batchSize` | `number` | `10` | Maximum events per request, from 1 to 100; a full batch is sent right away |
|
|
62
|
+
| `flushInterval` | `number` | `5000` | Milliseconds between sends of whatever is queued, at least 100 |
|
|
59
63
|
| `startedAt` | `number` | module load time | `Date.now()` when your SDK began initializing; reported as `time_to_init_ms` for the dashboard's init timing |
|
|
64
|
+
| `methods` | `string[]` | `[]` | Public methods of your SDK that are not wrapped with `trackMethod()`, so the dashboard's API Surface panel can show them when nobody calls them |
|
|
65
|
+
| `customer` | `{ id: string; name?: string }` | _(none)_ | The app or customer account this session runs for (see [Customers](#customers)) |
|
|
66
|
+
|
|
67
|
+
### API surface
|
|
68
|
+
|
|
69
|
+
Every name passed to `trackMethod()` is declared as part of your SDK's API surface, once per session (in the `sdk_initialized` event, or in one `api_surface` event for methods wrapped after `init()`). The dashboard lists those methods next to the ones people call, so the methods nobody uses show up with zero calls. Add methods you don't wrap with the `methods` option. Up to 500 names are declared.
|
|
70
|
+
|
|
71
|
+
### Customers
|
|
72
|
+
|
|
73
|
+
Tell SDK Garden which of your customers a session belongs to, and the dashboard's Customers page shows who is on an old version, who still calls a deprecated method and who hits errors, so you know who to contact.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// When your SDK knows which account it runs for, for example after resolving its API key:
|
|
77
|
+
SdkGarden.setCustomer({ id: account.id, name: account.displayName });
|
|
78
|
+
|
|
79
|
+
// Or at init, if you already know it:
|
|
80
|
+
SdkGarden.init({ apiKey: 'sgk_...', sdkName: 'my-sdk', sdkVersion: '1.0.0', customer: { id: 'acct_123' } });
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Use an ID from your own system, such as an account, project or app ID, and optionally a display name. Nothing is attributed unless you call this. Don't pass email addresses or other personal data: an ID that contains an email address is ignored, and so is a name that contains one. IDs are cut to 128 characters and names to 200. `setCustomer(null)` stops attributing; the customer lasts until the next `init()` or `shutdown()`.
|
|
60
84
|
|
|
61
85
|
## What gets sent
|
|
62
86
|
|
|
63
87
|
Each event carries your SDK's name and version, an event type, a random session ID created when `init()` runs, and a timestamp. Depending on the event:
|
|
64
88
|
|
|
65
|
-
- **`sdk_initialized`**: runtime (`node` + Node version, or `browser` + screen/viewport size, pixel ratio, timezone and language) and
|
|
89
|
+
- **`sdk_initialized`**: runtime (`node` + Node version, or `browser` + screen/viewport size, pixel ratio, timezone and language), `time_to_init_ms`, and the names of your SDK's methods (see [API surface](#api-surface)).
|
|
66
90
|
- **`method_called` / `method_success`**: method name, duration, sync/async, and the *number* of arguments.
|
|
67
91
|
- **`sdk_error`**: error type and message (email addresses are redacted) plus the method and duration.
|
|
92
|
+
- **If you set a customer**, every event carries its ID and name (see [Customers](#customers)).
|
|
68
93
|
- **In browsers**, every event also carries the page's origin (for example `https://shop.example.com`), never the full URL, path, query string or referrer.
|
|
69
94
|
|
|
70
|
-
Never sent: argument or return values, request or response bodies, cookies
|
|
95
|
+
Never sent: argument or return values, request or response bodies, cookies or stack traces. Error messages go out as they are apart from email addresses, so anything your SDK puts in an error message, such as a hostname, a URL or an ID, goes with it. Nothing is sent when `disabled: true`.
|
|
71
96
|
|
|
72
97
|
### Telling your users
|
|
73
98
|
|
|
74
99
|
Copy this into your SDK's README or privacy docs so your users know what's collected (edit the names to match):
|
|
75
100
|
|
|
76
|
-
> **Telemetry.** This SDK reports anonymous usage data to its maintainers through [SDK Garden](https://github.com/tjb/SDKGarden): the SDK version, runtime version, which SDK methods are called, how long they take, and
|
|
101
|
+
> **Telemetry.** This SDK reports anonymous usage data to its maintainers through [SDK Garden](https://github.com/tjb/SDKGarden): the SDK version, runtime version, which SDK methods are called, how long they take, and the type and message of the errors they raise (with email addresses removed). It never sends arguments, return values or request contents. To opt out, set `YOUR_SDK_TELEMETRY_DISABLED=1` *(wire this environment variable to `disabled: true` in your SDK)*.
|
|
77
102
|
|
|
78
|
-
##
|
|
103
|
+
## Sending and shutting down
|
|
79
104
|
|
|
80
|
-
|
|
105
|
+
Routine sends go out one request at a time: every `flushInterval` milliseconds, or as soon as `batchSize` events are queued. At most 1,000 events wait to be sent; if the endpoint cannot keep up, newer events are dropped. Events are also sent:
|
|
81
106
|
|
|
82
|
-
|
|
107
|
+
- **When a Node.js process runs out of work.** The client never keeps a process alive on its own. When your program finishes, the events still queued are sent before it exits, including any your own `beforeExit` handler tracks. In Node.js a request times out after 2 seconds, so an endpoint that does not answer delays exit by about 2 seconds (about 4 if a request was already running) but never keeps the process running. Only a DNS server that never answers can hold it longer, up to the system's DNS timeout.
|
|
108
|
+
- **When a page is hidden or unloaded**, in browsers, using `keepalive` so the request can outlive the page.
|
|
83
109
|
|
|
84
|
-
|
|
110
|
+
Two methods let you control this yourself. Both return promises that never reject:
|
|
85
111
|
|
|
86
|
-
### Async fire-and-forget calls (wrapper form only)
|
|
87
|
-
|
|
88
|
-
When using the **wrapper form**, `trackMethod` records `method_success` only when the caller `await`s or chains `.then()` on the returned promise. If the promise is discarded, `method_called` fires but `method_success` is never enqueued.
|
|
89
|
-
|
|
90
|
-
**Affected pattern:**
|
|
91
112
|
```typescript
|
|
92
|
-
//
|
|
93
|
-
SdkGarden.
|
|
94
|
-
```
|
|
113
|
+
// Send everything queued now and wait for it (at most 2 s by default), e.g. at the end of a serverless handler.
|
|
114
|
+
await SdkGarden.flush();
|
|
95
115
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
await SdkGarden.trackMethod('notify', notify)(...args);
|
|
116
|
+
// Send everything queued, then stop the client: no timer, no listeners, and tracking calls do nothing
|
|
117
|
+
// until init() runs again. Requests still running after 2 s (by default) are abandoned.
|
|
118
|
+
await SdkGarden.shutdown();
|
|
100
119
|
```
|
|
101
120
|
|
|
102
|
-
The
|
|
121
|
+
The automatic send does not run when the process ends through `process.exit()` or a signal such as Ctrl-C. If your SDK has a `close()` method or your users' code exits explicitly, `await SdkGarden.shutdown()` first.
|
|
122
|
+
|
|
123
|
+
Serverless functions and edge workers can be frozen as soon as a handler returns, so `await SdkGarden.flush()` before returning (in Cloudflare Workers, pass it to `ctx.waitUntil()`).
|
|
124
|
+
|
|
125
|
+
If a `beforeExit` handler of yours starts more work, such as the next job in a queue, `await SdkGarden.flush()` at the end of each job. While a process exits, the client sends only three times from `beforeExit`, so that a handler that tracks or flushes every time cannot keep the process alive; a `flush()` anywhere else always sends.
|
|
126
|
+
|
|
127
|
+
## Silent Failure Guarantee
|
|
128
|
+
|
|
129
|
+
All network errors are swallowed silently. SDK Garden will never throw or reject in your caller's context (not even `init()`), and `trackMethod` never changes what your function returns or throws. Wrapped functions always return exactly what the original returned. A native promise, also one from another realm such as a `vm` context, is watched until it settles (so a rejection nothing else handles is no longer reported as unhandled); Promise subclasses, such as an API client's response promise, and other thenables, such as lazy query builders, are never touched.
|
|
130
|
+
|
|
131
|
+
`sdk-garden-js` is one client per process: if two SDKs in the same app share an installed copy, the last `init()` wins for both. Bundle it into your SDK's build to give your SDK its own copy.
|
|
132
|
+
|
|
133
|
+
Pass `disabled: true` in test environments to suppress all network calls.
|
|
103
134
|
|
|
104
135
|
## License
|
|
105
136
|
|
package/dist/index.d.mts
CHANGED
|
@@ -7,7 +7,19 @@
|
|
|
7
7
|
* Security:
|
|
8
8
|
* - API key is never logged raw (see _sanitizeConfig).
|
|
9
9
|
* - Error messages are PII-scrubbed (email addresses redacted) before enqueueing.
|
|
10
|
-
* - All network errors
|
|
10
|
+
* - All network errors are swallowed silently — never propagated to callers.
|
|
11
|
+
*
|
|
12
|
+
* Lifecycle:
|
|
13
|
+
* - Routine sends go out one request at a time and at most MAX_QUEUE_SIZE
|
|
14
|
+
* events wait, so a burst of events cannot flood the host's network or the
|
|
15
|
+
* endpoint. flush() and the sends at exit or page hide send up to
|
|
16
|
+
* MAX_DRAIN_REQUESTS requests at once; shutdown() sends everything queued.
|
|
17
|
+
* - Timers are unref'd, so the client never keeps a Node process alive.
|
|
18
|
+
* - Queued events are sent when a Node process runs out of work (beforeExit)
|
|
19
|
+
* and when a page is hidden or unloaded (visibilitychange / pagehide).
|
|
20
|
+
* While a Node process exits, sending is limited so that it still ends,
|
|
21
|
+
* until the process shows that it carried on instead (see _checkExit).
|
|
22
|
+
* - No method throws into the host, and flush() and shutdown() never reject.
|
|
11
23
|
*/
|
|
12
24
|
/** Configuration for SdkGarden.init(). */
|
|
13
25
|
interface SdkGardenConfig {
|
|
@@ -17,15 +29,15 @@ interface SdkGardenConfig {
|
|
|
17
29
|
sdkName: string;
|
|
18
30
|
/** The version of your SDK (e.g. "1.2.3"). */
|
|
19
31
|
sdkVersion: string;
|
|
20
|
-
/** Override the default ingest endpoint. Default: https://ingest.sdkgarden.
|
|
32
|
+
/** Override the default ingest endpoint. Default: https://ingest.sdkgarden.com/track */
|
|
21
33
|
endpoint?: string;
|
|
22
34
|
/** Enable debug logging to console. Default: false */
|
|
23
35
|
debug?: boolean;
|
|
24
36
|
/** When true, all methods become no-ops — no events, no network calls. Default: false */
|
|
25
37
|
disabled?: boolean;
|
|
26
|
-
/** Maximum events per
|
|
38
|
+
/** Maximum events per request, from 1 to 100; a full batch is sent right away. Default: 10 */
|
|
27
39
|
batchSize?: number;
|
|
28
|
-
/**
|
|
40
|
+
/** Milliseconds between sends of whatever is queued, at least 100. Default: 5000 */
|
|
29
41
|
flushInterval?: number;
|
|
30
42
|
/**
|
|
31
43
|
* When your SDK started initializing, as a `Date.now()` timestamp. Used for
|
|
@@ -34,9 +46,31 @@ interface SdkGardenConfig {
|
|
|
34
46
|
* Default: when sdk-garden-js was first loaded.
|
|
35
47
|
*/
|
|
36
48
|
startedAt?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Names of your SDK's public methods that are not wrapped with
|
|
51
|
+
* trackMethod(). Sent once per session with every name passed to
|
|
52
|
+
* trackMethod(), so the dashboard can list the methods nobody calls.
|
|
53
|
+
*/
|
|
54
|
+
methods?: string[];
|
|
55
|
+
/**
|
|
56
|
+
* The app or customer account this session runs for, so the dashboard can
|
|
57
|
+
* show which customers are on old versions, call deprecated methods or hit
|
|
58
|
+
* errors. Use an ID from your own system (an account or project ID), never
|
|
59
|
+
* an email address or other personal data. Can also be set later with
|
|
60
|
+
* setCustomer(). Default: none.
|
|
61
|
+
*/
|
|
62
|
+
customer?: SdkGardenCustomer;
|
|
63
|
+
}
|
|
64
|
+
/** The app or customer account a session is attributed to (see setCustomer()). */
|
|
65
|
+
interface SdkGardenCustomer {
|
|
66
|
+
/** An opaque ID from your system, up to 128 characters, e.g. "acct_123". */
|
|
67
|
+
id: string;
|
|
68
|
+
/** A display name for the dashboard, up to 200 characters, e.g. "Acme Corp". */
|
|
69
|
+
name?: string;
|
|
37
70
|
}
|
|
38
71
|
/**
|
|
39
|
-
*
|
|
72
|
+
* Class method decorator returned by SdkGarden.trackMethod(name), for Stage 3
|
|
73
|
+
* decorators and for TypeScript's experimentalDecorators.
|
|
40
74
|
*
|
|
41
75
|
* @example
|
|
42
76
|
* class MySDK {
|
|
@@ -44,17 +78,10 @@ interface SdkGardenConfig {
|
|
|
44
78
|
* processPayment(amount: number): Receipt { ... }
|
|
45
79
|
* }
|
|
46
80
|
*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
* - No retry on 429 (v1)
|
|
52
|
-
* - No re-queue on failure (events are discarded)
|
|
53
|
-
* - Silent failure: catch() swallows all errors
|
|
54
|
-
*
|
|
55
|
-
* NOTE: _flush() is also exposed on the SdkGarden object for test access.
|
|
56
|
-
*/
|
|
57
|
-
declare function _flush(): void;
|
|
81
|
+
interface SdkMethodDecorator {
|
|
82
|
+
<This, Args extends unknown[], Return>(fn: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>): (this: This, ...args: Args) => Return;
|
|
83
|
+
<T>(target: object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T>;
|
|
84
|
+
}
|
|
58
85
|
/**
|
|
59
86
|
* Typed interface for the SdkGarden singleton.
|
|
60
87
|
* Declared separately so that trackMethod can have proper overload signatures —
|
|
@@ -66,9 +93,30 @@ interface SdkGardenObject {
|
|
|
66
93
|
/** Decorator form — use as @SdkGarden.trackMethod('name') on a class method. */
|
|
67
94
|
trackMethod(methodName: string): SdkMethodDecorator;
|
|
68
95
|
/** Wrapper form — pass an existing function, receive the instrumented version. */
|
|
69
|
-
trackMethod<T extends (...args:
|
|
96
|
+
trackMethod<T extends (...args: any[]) => any>(methodName: string, fn: T): T;
|
|
70
97
|
trackError(error: Error, context?: Record<string, unknown>): void;
|
|
71
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Attribute this session's events from now on to a customer, or pass null
|
|
100
|
+
* to stop. No-op before init().
|
|
101
|
+
*/
|
|
102
|
+
setCustomer(customer: SdkGardenCustomer | null): void;
|
|
103
|
+
/**
|
|
104
|
+
* Send every queued event now. Resolves once they (and any requests already
|
|
105
|
+
* in flight) have finished, or after `timeoutMs` (default 2000), whichever
|
|
106
|
+
* comes first. Never rejects.
|
|
107
|
+
*/
|
|
108
|
+
flush(timeoutMs?: number): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Send every queued event, then stop: no timer, no listeners, and tracking
|
|
111
|
+
* calls become no-ops until init() is called again. Resolves once the last
|
|
112
|
+
* requests finish; requests still running after `timeoutMs` (default 2000)
|
|
113
|
+
* are aborted so a Node process can exit. `0` stops at once without
|
|
114
|
+
* sending. Never rejects.
|
|
115
|
+
*/
|
|
116
|
+
shutdown(timeoutMs?: number): Promise<void>;
|
|
117
|
+
/** @deprecated Use flush(), which returns a promise. Kept so 0.1.0 code keeps working. */
|
|
118
|
+
_flush(): void;
|
|
119
|
+
/** @internal For unit tests: drop all state without sending anything. */
|
|
72
120
|
_reset(): void;
|
|
73
121
|
}
|
|
74
122
|
/**
|
|
@@ -84,9 +132,12 @@ interface SdkGardenObject {
|
|
|
84
132
|
* processPayment(amount: number): Receipt { ... }
|
|
85
133
|
* }
|
|
86
134
|
*
|
|
87
|
-
* // Wrapper form (standalone functions):
|
|
88
|
-
* const tracked = SdkGarden.trackMethod('processPayment', processPayment);
|
|
135
|
+
* // Wrapper form (standalone functions), safe to run before init():
|
|
136
|
+
* export const tracked = SdkGarden.trackMethod('processPayment', processPayment);
|
|
137
|
+
*
|
|
138
|
+
* // Before your SDK's host process exits (for example in your close()):
|
|
139
|
+
* await SdkGarden.shutdown();
|
|
89
140
|
*/
|
|
90
141
|
declare const SdkGarden: SdkGardenObject;
|
|
91
142
|
|
|
92
|
-
export { type SdkGardenConfig, type SdkMethodDecorator, SdkGarden as default };
|
|
143
|
+
export { type SdkGardenConfig, type SdkGardenCustomer, type SdkMethodDecorator, SdkGarden as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,19 @@
|
|
|
7
7
|
* Security:
|
|
8
8
|
* - API key is never logged raw (see _sanitizeConfig).
|
|
9
9
|
* - Error messages are PII-scrubbed (email addresses redacted) before enqueueing.
|
|
10
|
-
* - All network errors
|
|
10
|
+
* - All network errors are swallowed silently — never propagated to callers.
|
|
11
|
+
*
|
|
12
|
+
* Lifecycle:
|
|
13
|
+
* - Routine sends go out one request at a time and at most MAX_QUEUE_SIZE
|
|
14
|
+
* events wait, so a burst of events cannot flood the host's network or the
|
|
15
|
+
* endpoint. flush() and the sends at exit or page hide send up to
|
|
16
|
+
* MAX_DRAIN_REQUESTS requests at once; shutdown() sends everything queued.
|
|
17
|
+
* - Timers are unref'd, so the client never keeps a Node process alive.
|
|
18
|
+
* - Queued events are sent when a Node process runs out of work (beforeExit)
|
|
19
|
+
* and when a page is hidden or unloaded (visibilitychange / pagehide).
|
|
20
|
+
* While a Node process exits, sending is limited so that it still ends,
|
|
21
|
+
* until the process shows that it carried on instead (see _checkExit).
|
|
22
|
+
* - No method throws into the host, and flush() and shutdown() never reject.
|
|
11
23
|
*/
|
|
12
24
|
/** Configuration for SdkGarden.init(). */
|
|
13
25
|
interface SdkGardenConfig {
|
|
@@ -17,15 +29,15 @@ interface SdkGardenConfig {
|
|
|
17
29
|
sdkName: string;
|
|
18
30
|
/** The version of your SDK (e.g. "1.2.3"). */
|
|
19
31
|
sdkVersion: string;
|
|
20
|
-
/** Override the default ingest endpoint. Default: https://ingest.sdkgarden.
|
|
32
|
+
/** Override the default ingest endpoint. Default: https://ingest.sdkgarden.com/track */
|
|
21
33
|
endpoint?: string;
|
|
22
34
|
/** Enable debug logging to console. Default: false */
|
|
23
35
|
debug?: boolean;
|
|
24
36
|
/** When true, all methods become no-ops — no events, no network calls. Default: false */
|
|
25
37
|
disabled?: boolean;
|
|
26
|
-
/** Maximum events per
|
|
38
|
+
/** Maximum events per request, from 1 to 100; a full batch is sent right away. Default: 10 */
|
|
27
39
|
batchSize?: number;
|
|
28
|
-
/**
|
|
40
|
+
/** Milliseconds between sends of whatever is queued, at least 100. Default: 5000 */
|
|
29
41
|
flushInterval?: number;
|
|
30
42
|
/**
|
|
31
43
|
* When your SDK started initializing, as a `Date.now()` timestamp. Used for
|
|
@@ -34,9 +46,31 @@ interface SdkGardenConfig {
|
|
|
34
46
|
* Default: when sdk-garden-js was first loaded.
|
|
35
47
|
*/
|
|
36
48
|
startedAt?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Names of your SDK's public methods that are not wrapped with
|
|
51
|
+
* trackMethod(). Sent once per session with every name passed to
|
|
52
|
+
* trackMethod(), so the dashboard can list the methods nobody calls.
|
|
53
|
+
*/
|
|
54
|
+
methods?: string[];
|
|
55
|
+
/**
|
|
56
|
+
* The app or customer account this session runs for, so the dashboard can
|
|
57
|
+
* show which customers are on old versions, call deprecated methods or hit
|
|
58
|
+
* errors. Use an ID from your own system (an account or project ID), never
|
|
59
|
+
* an email address or other personal data. Can also be set later with
|
|
60
|
+
* setCustomer(). Default: none.
|
|
61
|
+
*/
|
|
62
|
+
customer?: SdkGardenCustomer;
|
|
63
|
+
}
|
|
64
|
+
/** The app or customer account a session is attributed to (see setCustomer()). */
|
|
65
|
+
interface SdkGardenCustomer {
|
|
66
|
+
/** An opaque ID from your system, up to 128 characters, e.g. "acct_123". */
|
|
67
|
+
id: string;
|
|
68
|
+
/** A display name for the dashboard, up to 200 characters, e.g. "Acme Corp". */
|
|
69
|
+
name?: string;
|
|
37
70
|
}
|
|
38
71
|
/**
|
|
39
|
-
*
|
|
72
|
+
* Class method decorator returned by SdkGarden.trackMethod(name), for Stage 3
|
|
73
|
+
* decorators and for TypeScript's experimentalDecorators.
|
|
40
74
|
*
|
|
41
75
|
* @example
|
|
42
76
|
* class MySDK {
|
|
@@ -44,17 +78,10 @@ interface SdkGardenConfig {
|
|
|
44
78
|
* processPayment(amount: number): Receipt { ... }
|
|
45
79
|
* }
|
|
46
80
|
*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
* - No retry on 429 (v1)
|
|
52
|
-
* - No re-queue on failure (events are discarded)
|
|
53
|
-
* - Silent failure: catch() swallows all errors
|
|
54
|
-
*
|
|
55
|
-
* NOTE: _flush() is also exposed on the SdkGarden object for test access.
|
|
56
|
-
*/
|
|
57
|
-
declare function _flush(): void;
|
|
81
|
+
interface SdkMethodDecorator {
|
|
82
|
+
<This, Args extends unknown[], Return>(fn: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>): (this: This, ...args: Args) => Return;
|
|
83
|
+
<T>(target: object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T>;
|
|
84
|
+
}
|
|
58
85
|
/**
|
|
59
86
|
* Typed interface for the SdkGarden singleton.
|
|
60
87
|
* Declared separately so that trackMethod can have proper overload signatures —
|
|
@@ -66,9 +93,30 @@ interface SdkGardenObject {
|
|
|
66
93
|
/** Decorator form — use as @SdkGarden.trackMethod('name') on a class method. */
|
|
67
94
|
trackMethod(methodName: string): SdkMethodDecorator;
|
|
68
95
|
/** Wrapper form — pass an existing function, receive the instrumented version. */
|
|
69
|
-
trackMethod<T extends (...args:
|
|
96
|
+
trackMethod<T extends (...args: any[]) => any>(methodName: string, fn: T): T;
|
|
70
97
|
trackError(error: Error, context?: Record<string, unknown>): void;
|
|
71
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Attribute this session's events from now on to a customer, or pass null
|
|
100
|
+
* to stop. No-op before init().
|
|
101
|
+
*/
|
|
102
|
+
setCustomer(customer: SdkGardenCustomer | null): void;
|
|
103
|
+
/**
|
|
104
|
+
* Send every queued event now. Resolves once they (and any requests already
|
|
105
|
+
* in flight) have finished, or after `timeoutMs` (default 2000), whichever
|
|
106
|
+
* comes first. Never rejects.
|
|
107
|
+
*/
|
|
108
|
+
flush(timeoutMs?: number): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Send every queued event, then stop: no timer, no listeners, and tracking
|
|
111
|
+
* calls become no-ops until init() is called again. Resolves once the last
|
|
112
|
+
* requests finish; requests still running after `timeoutMs` (default 2000)
|
|
113
|
+
* are aborted so a Node process can exit. `0` stops at once without
|
|
114
|
+
* sending. Never rejects.
|
|
115
|
+
*/
|
|
116
|
+
shutdown(timeoutMs?: number): Promise<void>;
|
|
117
|
+
/** @deprecated Use flush(), which returns a promise. Kept so 0.1.0 code keeps working. */
|
|
118
|
+
_flush(): void;
|
|
119
|
+
/** @internal For unit tests: drop all state without sending anything. */
|
|
72
120
|
_reset(): void;
|
|
73
121
|
}
|
|
74
122
|
/**
|
|
@@ -84,9 +132,12 @@ interface SdkGardenObject {
|
|
|
84
132
|
* processPayment(amount: number): Receipt { ... }
|
|
85
133
|
* }
|
|
86
134
|
*
|
|
87
|
-
* // Wrapper form (standalone functions):
|
|
88
|
-
* const tracked = SdkGarden.trackMethod('processPayment', processPayment);
|
|
135
|
+
* // Wrapper form (standalone functions), safe to run before init():
|
|
136
|
+
* export const tracked = SdkGarden.trackMethod('processPayment', processPayment);
|
|
137
|
+
*
|
|
138
|
+
* // Before your SDK's host process exits (for example in your close()):
|
|
139
|
+
* await SdkGarden.shutdown();
|
|
89
140
|
*/
|
|
90
141
|
declare const SdkGarden: SdkGardenObject;
|
|
91
142
|
|
|
92
|
-
export { type SdkGardenConfig, type SdkMethodDecorator, SdkGarden as default };
|
|
143
|
+
export { type SdkGardenConfig, type SdkGardenCustomer, type SdkMethodDecorator, SdkGarden as default };
|