spearkit 0.3.0 → 0.3.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/.claude/skills/spearkit/SKILL.md +236 -0
- package/.claude/skills/spearkit/reference/cheatsheet.md +218 -0
- package/AGENTS.md +164 -0
- package/README.md +13 -0
- package/docs/README.md +63 -0
- package/docs/api-reference.md +589 -0
- package/docs/client.md +207 -0
- package/docs/commands.md +198 -0
- package/docs/components.md +274 -0
- package/docs/context.md +201 -0
- package/docs/cooldown.md +124 -0
- package/docs/env.md +130 -0
- package/docs/events.md +152 -0
- package/docs/getting-started.md +147 -0
- package/docs/loading.md +142 -0
- package/docs/logging.md +195 -0
- package/docs/migration.md +160 -0
- package/docs/options.md +163 -0
- package/docs/plugins.md +116 -0
- package/docs/prefix.md +180 -0
- package/docs/scheduler.md +87 -0
- package/docs/usage.md +178 -0
- package/llms-full.txt +3367 -0
- package/llms.txt +39 -0
- package/package.json +9 -3
package/docs/usage.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Usage tracking
|
|
2
|
+
|
|
3
|
+
Usage tracking records **who used what**: every successful command, component,
|
|
4
|
+
and prefix-command invocation becomes a `UsageEvent` that spearkit can persist to a
|
|
5
|
+
store and/or mirror into a Discord channel. Turn it on with the client's `usage`
|
|
6
|
+
option.
|
|
7
|
+
|
|
8
|
+
## Usage tracking vs the logger
|
|
9
|
+
|
|
10
|
+
These look similar but answer different questions, and they are completely
|
|
11
|
+
independent sinks:
|
|
12
|
+
|
|
13
|
+
| | Logger | Usage tracking |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| Question | *What is the bot doing?* (diagnostics) | *Who used which feature?* (audit) |
|
|
16
|
+
| Content | Free-form messages, levels, errors, internals | Structured `UsageEvent`s for successful uses |
|
|
17
|
+
| Sinks | Console / your log pipeline | A database store and/or a Discord channel |
|
|
18
|
+
| Configured by | the `logger` option | the `usage` option |
|
|
19
|
+
|
|
20
|
+
A failed or errored command shows up in your **logs**; it is not recorded as a
|
|
21
|
+
usage event. Reach for the [logger](./logging.md) for debugging, and usage
|
|
22
|
+
tracking for analytics, audit trails, and "top commands" dashboards.
|
|
23
|
+
|
|
24
|
+
## Enabling it
|
|
25
|
+
|
|
26
|
+
Set the `usage` option. Provide a `store` (a database), a `channel` (a Discord
|
|
27
|
+
channel id to mirror events into), or both:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { MemoryUsageStore, SpearClient } from "spearkit";
|
|
31
|
+
|
|
32
|
+
const client = new SpearClient({
|
|
33
|
+
usage: {
|
|
34
|
+
store: new MemoryUsageStore(),
|
|
35
|
+
channel: "123456789012345678", // optional: also post each event here
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Once enabled, spearkit auto-tracks every successful command, component, and prefix
|
|
41
|
+
command — you write no tracking code in your handlers.
|
|
42
|
+
|
|
43
|
+
## The usage event
|
|
44
|
+
|
|
45
|
+
Each tracked use is a `UsageEvent`:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
interface UsageEvent {
|
|
49
|
+
type: "command" | "prefix" | "component" | "event";
|
|
50
|
+
name: string; // command/component/event name
|
|
51
|
+
userId?: string;
|
|
52
|
+
userTag?: string;
|
|
53
|
+
guildId?: string | null;
|
|
54
|
+
channelId?: string | null;
|
|
55
|
+
detail?: string; // free-form extra detail
|
|
56
|
+
timestamp: Date;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Stores (the database)
|
|
61
|
+
|
|
62
|
+
A store is any object implementing `UsageStore`:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
interface UsageStore {
|
|
66
|
+
record(event: UsageEvent): void | Promise<void>;
|
|
67
|
+
all(): UsageEvent[] | Promise<readonly UsageEvent[]>;
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
spearkit ships two.
|
|
72
|
+
|
|
73
|
+
### MemoryUsageStore
|
|
74
|
+
|
|
75
|
+
In-memory and synchronous — ideal for tests, prototypes, and live dashboards.
|
|
76
|
+
Pass an optional cap to keep only the most recent N events:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { MemoryUsageStore } from "spearkit";
|
|
80
|
+
|
|
81
|
+
const store = new MemoryUsageStore(1_000); // keep the last 1,000 events
|
|
82
|
+
|
|
83
|
+
store.all(); // readonly UsageEvent[]
|
|
84
|
+
store.size; // number of events held
|
|
85
|
+
store.byUser("123..."); // UsageEvent[] for one user id
|
|
86
|
+
store.clear(); // forget everything
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### JsonFileUsageStore
|
|
90
|
+
|
|
91
|
+
Durable and dependency-free: appends one event per line as newline-delimited
|
|
92
|
+
JSON (`.jsonl`). `all()` reads the file back and parses it, so it behaves like a
|
|
93
|
+
small file-backed database:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { JsonFileUsageStore } from "spearkit";
|
|
97
|
+
|
|
98
|
+
const store = new JsonFileUsageStore("./usage.jsonl");
|
|
99
|
+
|
|
100
|
+
await store.record({ type: "command", name: "ping", timestamp: new Date() });
|
|
101
|
+
const events = await store.all(); // readonly UsageEvent[]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The directory is created on demand. Because `all()` is async here (it reads from
|
|
105
|
+
disk), always `await` it.
|
|
106
|
+
|
|
107
|
+
## Querying the store
|
|
108
|
+
|
|
109
|
+
`client.usage.store` is the store you configured — query it directly. Note that
|
|
110
|
+
`all()` may be synchronous (`MemoryUsageStore`) or asynchronous
|
|
111
|
+
(`JsonFileUsageStore`); awaiting works for both:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
const store = client.usage.store;
|
|
115
|
+
if (store !== undefined) {
|
|
116
|
+
const events = await store.all();
|
|
117
|
+
const topCommand = events.filter((e) => e.type === "command").length;
|
|
118
|
+
console.log(`${topCommand} command uses recorded`);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## The Discord channel reporter
|
|
123
|
+
|
|
124
|
+
Besides (or instead of) a store, you can mirror each event into a Discord
|
|
125
|
+
channel. Pass `channel` (a channel id) in the `usage` option; spearkit posts one
|
|
126
|
+
line per event using `formatUsage`:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { SpearClient } from "spearkit";
|
|
130
|
+
|
|
131
|
+
new SpearClient({ usage: { channel: "123456789012345678" } });
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`formatUsage(event)` is the default renderer (e.g. `` `command` **ping** by
|
|
135
|
+
user#0001 in <#…> ``). Override it with `format` to control the line:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { SpearClient, type UsageEvent } from "spearkit";
|
|
139
|
+
|
|
140
|
+
new SpearClient({
|
|
141
|
+
usage: {
|
|
142
|
+
channel: "123456789012345678",
|
|
143
|
+
format: (event: UsageEvent) => `${event.userTag ?? "someone"} used ${event.name}`,
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## The usage tracker
|
|
149
|
+
|
|
150
|
+
`client.usage` is a `UsageTracker`. The client configures it from the `usage`
|
|
151
|
+
option, but you can drive it directly:
|
|
152
|
+
|
|
153
|
+
| Member | Description |
|
|
154
|
+
| ------ | ----------- |
|
|
155
|
+
| `setStore(store)` | Set (or swap) the persistence store. |
|
|
156
|
+
| `reportTo(channelId, format?)` | Mirror events into a channel, optionally with a custom formatter. |
|
|
157
|
+
| `track(event)` | Record a use. Returns immediately; storing/reporting run in the background. |
|
|
158
|
+
| `store` | The configured store, for querying. |
|
|
159
|
+
| `enabled` | `true` if a store or channel is configured. |
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import { JsonFileUsageStore } from "spearkit";
|
|
163
|
+
|
|
164
|
+
client.usage.setStore(new JsonFileUsageStore("./usage.jsonl"));
|
|
165
|
+
client.usage.reportTo("123456789012345678");
|
|
166
|
+
|
|
167
|
+
// Record a custom event yourself (e.g. a non-command action).
|
|
168
|
+
client.usage.track({ type: "event", name: "signup", timestamp: new Date() });
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Tracking is fire-and-forget: a slow store or channel never blocks command
|
|
172
|
+
handling, and any failure is logged rather than thrown.
|
|
173
|
+
|
|
174
|
+
## See also
|
|
175
|
+
|
|
176
|
+
- [Logging](./logging.md) — diagnostics, the other sink.
|
|
177
|
+
- [Commands](./commands.md) / [Prefix commands](./prefix.md) / [Components](./components.md) — what gets tracked.
|
|
178
|
+
- [Client](./client.md) — the `usage` option.
|