@boshyxd/rosentry 0.1.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/out/index.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { CaptureOptions, ConfigOptions, ScopeInterface, Trace, TraceOptions, TraceStatus } from "./types";
2
+ interface RoSentrySDK {
3
+ init(options: ConfigOptions): RoSentrySDK;
4
+ isInitialized(): boolean;
5
+ captureException(err: unknown, options?: CaptureOptions): string | undefined;
6
+ captureMessage(message: string, options?: CaptureOptions): string | undefined;
7
+ debug(message: string, data?: Map<string, unknown>): string | undefined;
8
+ info(message: string, data?: Map<string, unknown>): string | undefined;
9
+ warn(message: string, data?: Map<string, unknown>): string | undefined;
10
+ log(message: string, data?: Map<string, unknown>): string | undefined;
11
+ setUser(userId: number, playerName?: string, data?: Map<string, unknown>): void;
12
+ clearUser(): void;
13
+ addBreadcrumb(category: string, message: string, data?: Map<string, unknown>): void;
14
+ setTag(key: string, value: string): void;
15
+ setExtra(key: string, value: unknown): void;
16
+ wrap(fn: (...args: unknown[]) => unknown): (...args: unknown[]) => unknown;
17
+ withScope(callback: (scopeInterface: ScopeInterface) => void): void;
18
+ flush(): void;
19
+ enable(): void;
20
+ disable(): void;
21
+ getStatus(): {
22
+ initialized: boolean;
23
+ enabled: boolean;
24
+ queueSize: number;
25
+ };
26
+ startTrace(traceName: string, options?: TraceOptions): Trace | undefined;
27
+ getTrace(traceId: string): Trace | undefined;
28
+ endAllTraces(status?: TraceStatus): void;
29
+ getActiveTraceCount(): number;
30
+ }
31
+ declare const RoSentry: RoSentrySDK;
32
+ export = RoSentry;
package/out/init.luau ADDED
@@ -0,0 +1,229 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local RunService = TS.import(script, TS.getModule(script, "@rbxts", "services")).RunService
4
+ local Config = TS.import(script, script, "internal", "Config").Config
5
+ local Transport = TS.import(script, script, "internal", "Transport").Transport
6
+ local Scope = TS.import(script, script, "internal", "Scope").Scope
7
+ local Queue = TS.import(script, script, "internal", "Queue").Queue
8
+ local Capture = TS.import(script, script, "internal", "Capture").Capture
9
+ local AutoCapture = TS.import(script, script, "internal", "AutoCapture").AutoCapture
10
+ local TraceManager = TS.import(script, script, "internal", "Trace").TraceManager
11
+ local IS_SERVER = RunService:IsServer()
12
+ local config
13
+ local transport
14
+ local scope
15
+ local queue
16
+ local capture
17
+ local autoCapture
18
+ local traceManager
19
+ local initialized = false
20
+ local function debugLog(...)
21
+ local args = { ... }
22
+ if config and config:get("debug") then
23
+ print("[RoSentry]", unpack(args))
24
+ end
25
+ end
26
+ local function captureMessageImpl(message, options)
27
+ if not initialized then
28
+ warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
29
+ return nil
30
+ end
31
+ return capture:captureMessage(message, options)
32
+ end
33
+ local RoSentry
34
+ RoSentry = {
35
+ init = function(self, options)
36
+ if initialized then
37
+ warn("[RoSentry] Already initialized")
38
+ return RoSentry
39
+ end
40
+ config = Config.new()
41
+ config:init(options, IS_SERVER)
42
+ transport = Transport.new(config)
43
+ scope = Scope.new(config)
44
+ queue = Queue.new(config, transport)
45
+ capture = Capture.new(config, scope, queue)
46
+ autoCapture = AutoCapture.new(config, capture)
47
+ traceManager = TraceManager.new(config, scope, queue)
48
+ if IS_SERVER then
49
+ transport:setupServerRelay()
50
+ end
51
+ queue:startFlushLoop()
52
+ if config:get("autoCapture") then
53
+ autoCapture:setup()
54
+ end
55
+ initialized = true
56
+ debugLog("Initialized with environment:", config:get("environment"), if IS_SERVER then "(server)" else "(client)")
57
+ scope:addBreadcrumb("sdk", "RoSentry initialized", {
58
+ environment = config:get("environment"),
59
+ placeId = game.PlaceId,
60
+ })
61
+ return RoSentry
62
+ end,
63
+ isInitialized = function(self)
64
+ return initialized
65
+ end,
66
+ captureException = function(self, err, options)
67
+ if not initialized then
68
+ warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
69
+ return nil
70
+ end
71
+ return capture:captureException(err, options)
72
+ end,
73
+ captureMessage = function(self, message, options)
74
+ return captureMessageImpl(message, options)
75
+ end,
76
+ debug = function(self, message, data)
77
+ return captureMessageImpl(message, {
78
+ level = "debug",
79
+ context = data,
80
+ })
81
+ end,
82
+ info = function(self, message, data)
83
+ return captureMessageImpl(message, {
84
+ level = "info",
85
+ context = data,
86
+ })
87
+ end,
88
+ warn = function(self, message, data)
89
+ return captureMessageImpl(message, {
90
+ level = "warn",
91
+ context = data,
92
+ })
93
+ end,
94
+ log = function(self, message, data)
95
+ return captureMessageImpl(message, {
96
+ level = "info",
97
+ context = data,
98
+ })
99
+ end,
100
+ setUser = function(self, userId, playerName, data)
101
+ if not initialized then
102
+ warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
103
+ return nil
104
+ end
105
+ scope:setUser(userId, playerName, data)
106
+ end,
107
+ clearUser = function(self)
108
+ if not initialized then
109
+ return nil
110
+ end
111
+ scope:clearUser()
112
+ end,
113
+ addBreadcrumb = function(self, category, message, data)
114
+ if not initialized then
115
+ return nil
116
+ end
117
+ scope:addBreadcrumb(category, message, data)
118
+ end,
119
+ setTag = function(self, key, value)
120
+ if not initialized then
121
+ return nil
122
+ end
123
+ scope:setTag(key, value)
124
+ end,
125
+ setExtra = function(self, key, value)
126
+ if not initialized then
127
+ return nil
128
+ end
129
+ scope:setExtra(key, value)
130
+ end,
131
+ wrap = function(self, fn)
132
+ if not initialized then
133
+ warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
134
+ return fn
135
+ end
136
+ return capture:wrap(fn)
137
+ end,
138
+ withScope = function(self, callback)
139
+ if not initialized then
140
+ warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
141
+ return nil
142
+ end
143
+ local isolatedScope = scope:clone()
144
+ local scopeInterface = {
145
+ setUser = function(userId, playerName, data)
146
+ isolatedScope:setUser(userId, playerName, data)
147
+ end,
148
+ clearUser = function()
149
+ isolatedScope:clearUser()
150
+ end,
151
+ addBreadcrumb = function(category, message, data)
152
+ isolatedScope:addBreadcrumb(category, message, data)
153
+ end,
154
+ setTag = function(key, value)
155
+ isolatedScope:setTag(key, value)
156
+ end,
157
+ setExtra = function(key, value)
158
+ isolatedScope:setExtra(key, value)
159
+ end,
160
+ }
161
+ local originalScope = scope
162
+ scope = isolatedScope
163
+ capture:setScope(isolatedScope)
164
+ traceManager:setScope(isolatedScope)
165
+ local success, err = pcall(function()
166
+ return callback(scopeInterface)
167
+ end)
168
+ scope = originalScope
169
+ capture:setScope(originalScope)
170
+ traceManager:setScope(originalScope)
171
+ if not success then
172
+ capture:captureException(err)
173
+ error(err)
174
+ end
175
+ end,
176
+ flush = function(self)
177
+ if not initialized then
178
+ return nil
179
+ end
180
+ queue:flush()
181
+ end,
182
+ enable = function(self)
183
+ if not initialized then
184
+ return nil
185
+ end
186
+ config:enable()
187
+ debugLog("SDK enabled")
188
+ end,
189
+ disable = function(self)
190
+ if not initialized then
191
+ return nil
192
+ end
193
+ config:disable()
194
+ debugLog("SDK disabled")
195
+ end,
196
+ getStatus = function(self)
197
+ return {
198
+ initialized = initialized,
199
+ enabled = if initialized then config:isEnabled() else false,
200
+ queueSize = if initialized then queue:getSize() else 0,
201
+ }
202
+ end,
203
+ startTrace = function(self, traceName, options)
204
+ if not initialized then
205
+ warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
206
+ return nil
207
+ end
208
+ return traceManager:startTrace(traceName, options)
209
+ end,
210
+ getTrace = function(self, traceId)
211
+ if not initialized then
212
+ return nil
213
+ end
214
+ return traceManager:getTrace(traceId)
215
+ end,
216
+ endAllTraces = function(self, status)
217
+ if not initialized then
218
+ return nil
219
+ end
220
+ traceManager:endAllTraces(status)
221
+ end,
222
+ getActiveTraceCount = function(self)
223
+ if not initialized then
224
+ return 0
225
+ end
226
+ return traceManager:getActiveCount()
227
+ end,
228
+ }
229
+ return RoSentry
@@ -0,0 +1,13 @@
1
+ import { Config } from "./Config";
2
+ import { Capture } from "./Capture";
3
+ export declare class AutoCapture {
4
+ private _config;
5
+ private _capture;
6
+ private _connections;
7
+ private _enabled;
8
+ constructor(config: Config, capture: Capture);
9
+ private _debug;
10
+ setup(): void;
11
+ teardown(): void;
12
+ isEnabled(): boolean;
13
+ }
@@ -0,0 +1,74 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local _services = TS.import(script, TS.getModule(script, "@rbxts", "services"))
4
+ local ScriptContext = _services.ScriptContext
5
+ local LogService = _services.LogService
6
+ local AutoCapture
7
+ do
8
+ AutoCapture = setmetatable({}, {
9
+ __tostring = function()
10
+ return "AutoCapture"
11
+ end,
12
+ })
13
+ AutoCapture.__index = AutoCapture
14
+ function AutoCapture.new(...)
15
+ local self = setmetatable({}, AutoCapture)
16
+ return self:constructor(...) or self
17
+ end
18
+ function AutoCapture:constructor(config, capture)
19
+ self._config = config
20
+ self._capture = capture
21
+ self._connections = {}
22
+ self._enabled = false
23
+ end
24
+ function AutoCapture:_debug(...)
25
+ local args = { ... }
26
+ if self._config:get("debug") then
27
+ print("[RoSentry:AutoCapture]", unpack(args))
28
+ end
29
+ end
30
+ function AutoCapture:setup()
31
+ if self._enabled then
32
+ self:_debug("Auto-capture already enabled")
33
+ return nil
34
+ end
35
+ local errorConnection = ScriptContext.Error:Connect(function(message, stackTrace, scriptInstance)
36
+ if not self._config:isEnabled() then
37
+ return nil
38
+ end
39
+ self._capture:captureScriptError(message, stackTrace, scriptInstance)
40
+ end)
41
+ local _exp = self._connections
42
+ table.insert(_exp, errorConnection)
43
+ if self._config:get("captureWarnings") then
44
+ local warningConnection = LogService.MessageOut:Connect(function(message, messageType)
45
+ if not self._config:isEnabled() then
46
+ return nil
47
+ end
48
+ if messageType == Enum.MessageType.MessageWarning then
49
+ self._capture:captureMessage(message, {
50
+ level = "warn",
51
+ })
52
+ end
53
+ end)
54
+ local _exp_1 = self._connections
55
+ table.insert(_exp_1, warningConnection)
56
+ end
57
+ self._enabled = true
58
+ self:_debug("Auto-capture enabled")
59
+ end
60
+ function AutoCapture:teardown()
61
+ for _, connection in self._connections do
62
+ connection:Disconnect()
63
+ end
64
+ self._connections = {}
65
+ self._enabled = false
66
+ self:_debug("Auto-capture disabled")
67
+ end
68
+ function AutoCapture:isEnabled()
69
+ return self._enabled
70
+ end
71
+ end
72
+ return {
73
+ AutoCapture = AutoCapture,
74
+ }
@@ -0,0 +1,17 @@
1
+ import { CaptureOptions } from "../types";
2
+ import { Config } from "./Config";
3
+ import { Scope } from "./Scope";
4
+ import { Queue } from "./Queue";
5
+ export declare class Capture {
6
+ private _config;
7
+ private _scope;
8
+ private _queue;
9
+ constructor(config: Config, scope: Scope, queue: Queue);
10
+ private _debug;
11
+ private _buildErrorData;
12
+ captureException(err: unknown, options?: CaptureOptions): string | undefined;
13
+ captureMessage(message: string, options?: CaptureOptions): string | undefined;
14
+ captureScriptError(message: string, stackTrace: string, scriptInstance?: Instance): string | undefined;
15
+ wrap(fn: (...args: unknown[]) => unknown): (...args: unknown[]) => unknown;
16
+ setScope(scope: Scope): void;
17
+ }
@@ -0,0 +1,142 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local _util = TS.import(script, script.Parent, "util")
4
+ local generateUUID = _util.generateUUID
5
+ local getJobId = _util.getJobId
6
+ local getPlaceId = _util.getPlaceId
7
+ local getGameVersion = _util.getGameVersion
8
+ local isServer = _util.isServer
9
+ local sanitizeStackTrace = _util.sanitizeStackTrace
10
+ local getTimestamp = _util.getTimestamp
11
+ local Capture
12
+ do
13
+ Capture = setmetatable({}, {
14
+ __tostring = function()
15
+ return "Capture"
16
+ end,
17
+ })
18
+ Capture.__index = Capture
19
+ function Capture.new(...)
20
+ local self = setmetatable({}, Capture)
21
+ return self:constructor(...) or self
22
+ end
23
+ function Capture:constructor(config, scope, queue)
24
+ self._config = config
25
+ self._scope = scope
26
+ self._queue = queue
27
+ end
28
+ function Capture:_debug(...)
29
+ local args = { ... }
30
+ if self._config:get("debug") then
31
+ print("[RoSentry:Capture]", unpack(args))
32
+ end
33
+ end
34
+ function Capture:_buildErrorData(message, level, stackTrace, options)
35
+ local opts = options or {}
36
+ local user = self._scope:getUser()
37
+ local breadcrumbs = self._scope:getBreadcrumbs()
38
+ local tags = self._scope:getTags()
39
+ local extras = self._scope:getExtras()
40
+ local allTags = {}
41
+ -- ▼ ReadonlyMap.forEach ▼
42
+ local _callback = function(value, key)
43
+ local _arg0 = `{key}:{value}`
44
+ table.insert(allTags, _arg0)
45
+ end
46
+ for _k, _v in tags do
47
+ _callback(_v, _k, tags)
48
+ end
49
+ -- ▲ ReadonlyMap.forEach ▲
50
+ if opts.tags then
51
+ for _, tag in opts.tags do
52
+ table.insert(allTags, tag)
53
+ end
54
+ end
55
+ local errorData = {
56
+ message = message,
57
+ level = opts.level or level,
58
+ stack_trace = sanitizeStackTrace(stackTrace),
59
+ user_id = if user then user.id else nil,
60
+ player_name = if user then user.name else nil,
61
+ job_id = getJobId(),
62
+ place_id = getPlaceId(),
63
+ game_version = getGameVersion(),
64
+ environment = self._config:get("environment"),
65
+ context = {
66
+ userData = if user then user.data else nil,
67
+ custom = opts.context or extras,
68
+ breadcrumbs = breadcrumbs,
69
+ isServer = isServer(),
70
+ script = nil,
71
+ },
72
+ tags = allTags,
73
+ timestamp = getTimestamp(),
74
+ }
75
+ return errorData
76
+ end
77
+ function Capture:captureException(err, options)
78
+ if not self._config:isEnabled() then
79
+ return nil
80
+ end
81
+ local opts = options or {}
82
+ local message = tostring(err)
83
+ local _condition = opts.stackTrace
84
+ if _condition == nil then
85
+ _condition = debug.traceback()
86
+ end
87
+ local stackTrace = _condition
88
+ local errorData = self:_buildErrorData(message, "error", stackTrace, opts)
89
+ local success = self._queue:push(errorData)
90
+ if success then
91
+ self:_debug("Captured exception:", message)
92
+ return generateUUID()
93
+ end
94
+ return nil
95
+ end
96
+ function Capture:captureMessage(message, options)
97
+ if not self._config:isEnabled() then
98
+ return nil
99
+ end
100
+ local opts = options or {}
101
+ local level = opts.level or "info"
102
+ local errorData = self:_buildErrorData(message, level, nil, opts)
103
+ local success = self._queue:push(errorData)
104
+ if success then
105
+ self:_debug("Captured message:", message)
106
+ return generateUUID()
107
+ end
108
+ return nil
109
+ end
110
+ function Capture:captureScriptError(message, stackTrace, scriptInstance)
111
+ if not self._config:isEnabled() then
112
+ return nil
113
+ end
114
+ local errorData = self:_buildErrorData(message, "error", stackTrace)
115
+ errorData.context.script = if scriptInstance then scriptInstance:GetFullName() else "Unknown"
116
+ local success = self._queue:push(errorData)
117
+ if success then
118
+ self:_debug("Captured script error:", message)
119
+ return generateUUID()
120
+ end
121
+ return nil
122
+ end
123
+ function Capture:wrap(fn)
124
+ return function(...)
125
+ local args = { ... }
126
+ local success, result = pcall(function()
127
+ return fn(unpack(args))
128
+ end)
129
+ if not success then
130
+ self:captureException(result)
131
+ error(result)
132
+ end
133
+ return result
134
+ end
135
+ end
136
+ function Capture:setScope(scope)
137
+ self._scope = scope
138
+ end
139
+ end
140
+ return {
141
+ Capture = Capture,
142
+ }
@@ -0,0 +1,12 @@
1
+ import { Config as ConfigType, ConfigOptions } from "../types";
2
+ export declare class Config {
3
+ private _config;
4
+ constructor();
5
+ init(options: ConfigOptions, isServer: boolean): void;
6
+ get<T extends keyof ConfigType>(key: T): ConfigType[T];
7
+ set<T extends keyof ConfigType>(key: T, value: ConfigType[T]): void;
8
+ getAll(): ConfigType;
9
+ isEnabled(): boolean;
10
+ enable(): void;
11
+ disable(): void;
12
+ }
@@ -0,0 +1,116 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local DEFAULT_CONFIG = {
3
+ apiKey = "",
4
+ environment = "production",
5
+ endpoint = "https://rosentry.vercel.app/api/ingest",
6
+ enabled = true,
7
+ sampleRate = 1.0,
8
+ maxBreadcrumbs = 100,
9
+ maxQueueSize = 50,
10
+ flushInterval = 5,
11
+ debug = false,
12
+ autoCapture = true,
13
+ captureWarnings = false,
14
+ beforeSend = nil,
15
+ }
16
+ local Config
17
+ do
18
+ Config = setmetatable({}, {
19
+ __tostring = function()
20
+ return "Config"
21
+ end,
22
+ })
23
+ Config.__index = Config
24
+ function Config.new(...)
25
+ local self = setmetatable({}, Config)
26
+ return self:constructor(...) or self
27
+ end
28
+ function Config:constructor()
29
+ local _object = table.clone(DEFAULT_CONFIG)
30
+ setmetatable(_object, nil)
31
+ self._config = _object
32
+ end
33
+ function Config:init(options, isServer)
34
+ if isServer then
35
+ local _arg0 = options.apiKey ~= nil and options.apiKey ~= ""
36
+ assert(_arg0, "[RoSentry] apiKey is required on server")
37
+ end
38
+ local _condition = options.apiKey
39
+ if _condition == nil then
40
+ _condition = ""
41
+ end
42
+ self._config.apiKey = _condition
43
+ local _condition_1 = options.environment
44
+ if _condition_1 == nil then
45
+ _condition_1 = self._config.environment
46
+ end
47
+ self._config.environment = _condition_1
48
+ local _condition_2 = options.endpoint
49
+ if _condition_2 == nil then
50
+ _condition_2 = self._config.endpoint
51
+ end
52
+ self._config.endpoint = _condition_2
53
+ local _condition_3 = options.enabled
54
+ if _condition_3 == nil then
55
+ _condition_3 = self._config.enabled
56
+ end
57
+ self._config.enabled = _condition_3
58
+ local _condition_4 = options.sampleRate
59
+ if _condition_4 == nil then
60
+ _condition_4 = self._config.sampleRate
61
+ end
62
+ self._config.sampleRate = _condition_4
63
+ local _condition_5 = options.maxBreadcrumbs
64
+ if _condition_5 == nil then
65
+ _condition_5 = self._config.maxBreadcrumbs
66
+ end
67
+ self._config.maxBreadcrumbs = _condition_5
68
+ local _condition_6 = options.maxQueueSize
69
+ if _condition_6 == nil then
70
+ _condition_6 = self._config.maxQueueSize
71
+ end
72
+ self._config.maxQueueSize = _condition_6
73
+ local _condition_7 = options.flushInterval
74
+ if _condition_7 == nil then
75
+ _condition_7 = self._config.flushInterval
76
+ end
77
+ self._config.flushInterval = _condition_7
78
+ local _condition_8 = options.debug
79
+ if _condition_8 == nil then
80
+ _condition_8 = self._config.debug
81
+ end
82
+ self._config.debug = _condition_8
83
+ local _condition_9 = options.autoCapture
84
+ if _condition_9 == nil then
85
+ _condition_9 = self._config.autoCapture
86
+ end
87
+ self._config.autoCapture = _condition_9
88
+ local _condition_10 = options.captureWarnings
89
+ if _condition_10 == nil then
90
+ _condition_10 = self._config.captureWarnings
91
+ end
92
+ self._config.captureWarnings = _condition_10
93
+ self._config.beforeSend = options.beforeSend
94
+ end
95
+ function Config:get(key)
96
+ return self._config[key]
97
+ end
98
+ function Config:set(key, value)
99
+ self._config[key] = value
100
+ end
101
+ function Config:getAll()
102
+ return self._config
103
+ end
104
+ function Config:isEnabled()
105
+ return self._config.enabled
106
+ end
107
+ function Config:enable()
108
+ self._config.enabled = true
109
+ end
110
+ function Config:disable()
111
+ self._config.enabled = false
112
+ end
113
+ end
114
+ return {
115
+ Config = Config,
116
+ }
@@ -0,0 +1,19 @@
1
+ import { ErrorData } from "../types";
2
+ import { Config } from "./Config";
3
+ import { Transport } from "./Transport";
4
+ export declare class Queue {
5
+ private _config;
6
+ private _transport;
7
+ private _queue;
8
+ private _lastFlush;
9
+ private _flushLoopRunning;
10
+ constructor(config: Config, transport: Transport);
11
+ private _debug;
12
+ private _shouldSample;
13
+ push(errorData: ErrorData): boolean;
14
+ flush(): void;
15
+ startFlushLoop(): void;
16
+ stopFlushLoop(): void;
17
+ getSize(): number;
18
+ clear(): void;
19
+ }