@rbxts/zyntex-sdk 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 delucted
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,8 @@
1
+ # zyntex-sdk
2
+ The Roblox Zyntex SDK.
3
+
4
+ Types may not be complete, I am adding them as I use them.
5
+
6
+ # Download
7
+ To download the SDK, please follow the instructions in the Zyntex documentation:
8
+ https://docs.zyntex.dev/download
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@rbxts/zyntex-sdk",
3
+ "version": "1.0.0",
4
+ "description": "Typescript types for: The Roblox Zyntex SDK.",
5
+ "main": "src/init.lua",
6
+ "scripts": {
7
+ "build": "rbxtsc",
8
+ "watch": "rbxtsc -w",
9
+ "prepublishOnly": "npm run build"
10
+ },
11
+ "keywords": [],
12
+ "license": "MIT",
13
+ "types": "src/index.d.ts",
14
+ "files": [
15
+ "src"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "devDependencies": {
21
+ "@rbxts/compiler-types": "^3.0.0-types.0",
22
+ "@rbxts/types": "^1.0.867",
23
+ "@typescript-eslint/eslint-plugin": "^8.38.0",
24
+ "@typescript-eslint/parser": "^8.38.0",
25
+ "eslint": "^9.32.0",
26
+ "eslint-plugin-roblox-ts": "^1.0.0",
27
+ "roblox-ts": "^3.0.0",
28
+ "typescript": "^5.8.3"
29
+ }
30
+ }
@@ -0,0 +1,176 @@
1
+ local Session = require(script.Parent:WaitForChild("api"))
2
+ local HttpService = game:GetService("HttpService")
3
+
4
+ local Telemetry = {}
5
+ Telemetry.__index = Telemetry
6
+
7
+ export type LabelSet = { [string]: string }
8
+
9
+ export type MetricOpts = {
10
+ --[[
11
+ Optional human-readable description
12
+ ]]
13
+ description: string?,
14
+ --[[
15
+ Labels, used for filtering metrics on the dashboard
16
+ ]]
17
+ labels: { string }?,
18
+ --[[
19
+ Only for Histogram
20
+ ]]
21
+ buckets: { number }?,
22
+ }
23
+
24
+ export type CounterMetric = {
25
+ inc: (self: CounterMetric, delta: number?, labels: LabelSet?) -> (),
26
+ }
27
+
28
+ export type GaugeMetric = {
29
+ set: (self: GaugeMetric, value: number, labels: LabelSet?) -> (),
30
+ inc: (self: GaugeMetric, delta: number?, labels: LabelSet?) -> (),
31
+ dec: (self: GaugeMetric, delta: number?, labels: LabelSet?) -> (),
32
+ }
33
+
34
+ export type HistogramMetric = {
35
+ observe: (self: HistogramMetric, value: number, labels: LabelSet?) -> (),
36
+ }
37
+
38
+ export type SummaryMetric = {
39
+ observe: (self: SummaryMetric, value: number, labels: LabelSet?) -> (),
40
+ }
41
+
42
+ function Telemetry.new(registryName: string?, flushEvery: number?, session: Session.Session)
43
+ return setmetatable({
44
+ _name = registryName or "default",
45
+ _buffer = {}, -- pending samples
46
+ _flushEvery = flushEvery or 10,
47
+ _lastFlush = os.clock(),
48
+ _session = session
49
+ }, Telemetry)
50
+ end
51
+
52
+ --[[
53
+ Generic pushSample shared by all metric types
54
+ ]]
55
+ local function pushSample(self, kind: string, name: string, value, labels: LabelSet)
56
+ table.insert(self._buffer, {
57
+ t = os.time(), -- UTC seconds
58
+ k = kind, -- counter | gauge | hist | sum
59
+ n = name, -- metric name
60
+ v = value, -- number or bucket-map
61
+ l = labels -- table<string,string>
62
+ })
63
+
64
+ if os.clock() - self._lastFlush >= self._flushEvery then
65
+ self:flush()
66
+ end
67
+ end
68
+
69
+ function Telemetry:flush()
70
+ if #self._buffer == 0 then return end
71
+ pcall(function()
72
+ self._session:post(
73
+ "/telemetry/push",
74
+ {buffer = self._buffer}
75
+ )
76
+ end)
77
+ self._buffer, self._lastFlush = {}, os.clock()
78
+ end
79
+
80
+ --[[
81
+ Creates (or fetches) a monotonically increasing **counter** metric.
82
+
83
+ @param self Telemetry – the registry instance.
84
+ @param name string – metric name (snake_case).
85
+ @param opts MetricOpts? – optional descriptor & label schema.
86
+
87
+ @return CounterMetric handle – call `:inc()` to push samples.
88
+
89
+ Example
90
+ ```lua
91
+ local shots = registry:Counter("weapon_shots_total", {
92
+ description = "Number of shots fired per weapon",
93
+ labels = {"weapon"}
94
+ })
95
+
96
+ shots:inc() -- +1
97
+ shots:inc(3, {weapon="AK-47"}) -- +3 with a label
98
+ ```
99
+ ]]--
100
+ function Telemetry:Counter(name: string, opts: MetricOpts?): CounterMetric
101
+ local total = 0
102
+ return ({
103
+ inc = function(_: CounterMetric, delta: number?, lbls: LabelSet?)
104
+ total += delta or 1
105
+ pushSample(self, "counter", name, total, lbls or {})
106
+ end,
107
+ } :: any) :: CounterMetric
108
+ end
109
+
110
+ --[[
111
+ Creates a **gauge** metric – an instantaneous value that can go up
112
+ or down (e.g. memory, player count, FPS).
113
+
114
+ `set()` overrides the value directly, while `inc()` / `dec()` apply
115
+ deltas.
116
+
117
+ @return GaugeMetric handle.
118
+ ]]--
119
+ function Telemetry:Gauge(name: string, opts: MetricOpts?): GaugeMetric
120
+ return ({
121
+
122
+ set = function(_: GaugeMetric, value: number, lbls: LabelSet?)
123
+ pushSample(self, "gauge", name, value, lbls or {})
124
+ end,
125
+
126
+ inc = function(_: GaugeMetric, delta: number?, lbls: LabelSet?)
127
+ pushSample(self, "gauge", name, delta or 1, lbls or {})
128
+ end,
129
+
130
+ dec = function(_: GaugeMetric, delta: number?, lbls: LabelSet?)
131
+ pushSample(self, "gauge", name, -(delta or 1), lbls or {})
132
+ end,
133
+
134
+ } :: any) :: GaugeMetric
135
+ end
136
+
137
+ --[[
138
+ Creates a **histogram** metric – captures a distribution of values
139
+ (e.g. damage dealt, ping). `buckets` may be provided in `opts`.
140
+
141
+ The raw sample value is sent unchanged; bucketing happens on the
142
+ back-end so bucket definitions can evolve without client updates.
143
+
144
+ @return HistogramMetric handle.
145
+ ]]--
146
+ function Telemetry:Histogram(name: string, opts: MetricOpts?): HistogramMetric
147
+ local buckets: {number}? = opts and opts.buckets
148
+ return ({
149
+
150
+ observe = function(_: HistogramMetric, value: number, lbls: LabelSet?)
151
+ local combined: LabelSet = lbls and table.clone(lbls) or {}
152
+ if buckets then combined._buckets = HttpService:JSONEncode(buckets) end
153
+ pushSample(self, "hist", name, value, combined)
154
+ end,
155
+
156
+ } :: any) :: HistogramMetric
157
+ end
158
+
159
+ --[[
160
+ Creates a **summary** metric – similar to histogram but intended
161
+ for quantile estimation (P-style summaries). Uses a single `observe`
162
+ method.
163
+
164
+ @return SummaryMetric handle.
165
+ ]]--
166
+ function Telemetry:Summary(name: string, opts: MetricOpts?): SummaryMetric
167
+ return ({
168
+
169
+ observe = function(_: SummaryMetric, value: number, lbls: LabelSet?)
170
+ pushSample(self, "sum", name, value, lbls or {})
171
+ end,
172
+
173
+ } :: any) :: SummaryMetric
174
+ end
175
+
176
+ return Telemetry