react-ui-basics 0.0.224 → 0.0.226

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/index.js CHANGED
@@ -26,6 +26,8 @@ export { default as Modal } from './Modal.js';
26
26
  export { default as ModalMenu } from './ModalMenu.js';
27
27
  export { default as Router } from './router/index.js';
28
28
  export { default as Scrollable } from './Scrollable.js';
29
+ import * as SimpleSentryClient from './misc/SimpleSentryClient.js';
30
+ export { SimpleSentryClient };
29
31
  export { default as Size } from './Size.js';
30
32
  export { default as Snackbar } from './Snackbar.js';
31
33
  export { default as SpinningProgress } from './SpinningProgress.js';
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,48 @@
1
+ interface Context {
2
+ extra: any;
3
+ }
4
+ interface User {
5
+ id?: string | number;
6
+ name?: string;
7
+ username?: string;
8
+ email?: string;
9
+ }
10
+ interface Request {
11
+ url: string;
12
+ headers: {
13
+ [key: string]: string;
14
+ };
15
+ }
16
+ declare class Scope {
17
+ user: User;
18
+ dsn: string;
19
+ release: string;
20
+ environment: string;
21
+ userAgent: string;
22
+ url: string;
23
+ setUser(userProps: User): void;
24
+ }
25
+ interface Payload {
26
+ level: string;
27
+ exception: any;
28
+ event_id: string;
29
+ platform: string;
30
+ timestamp: number;
31
+ environment: string;
32
+ release: string;
33
+ request: Request;
34
+ extra: any;
35
+ user: User;
36
+ }
37
+ declare type PayloadInterceptor = (payload: Payload, context: Context) => (Payload | null);
38
+ export declare const init: (args: {
39
+ dsn: string;
40
+ release: string;
41
+ environment: string;
42
+ }) => void;
43
+ export declare const captureException: (e: Error | string, context: Context) => void;
44
+ export declare const configureScope: (f: (scope: Scope) => void) => void;
45
+ export declare const setPayloadInterceptor: (interceptor: PayloadInterceptor) => void;
46
+ export declare const setOnPostSuccess: (onSuccess: any) => void;
47
+ export declare const setOnErrorSuccess: (onError: any) => void;
48
+ export {};
@@ -0,0 +1,169 @@
1
+ import ReactConstants from "./../ReactConstants"; import {clientHeight as __clientHeight, clientWidth as __clientWidth, createAccessor as __createAccessor, data as __data, height as __height, left as __left, length as __length, pageX as __pageX, pageY as __pageY, props as __props, scrollLeft as __scrollLeft, scrollTop as __scrollTop, state as __state, style as __style, target as __target, top as __top, value as __value, width as __width} from "./../CommonFields"; import {toConsumableArray as __toConsumableArray} from "./../_virtual/_rollupPluginBabelHelpers"; import {extends as __extends} from "./../_virtual/_rollupPluginBabelHelpers"; import {inherits as __inherits} from "./../_virtual/_rollupPluginBabelHelpers"; import { fetch } from '../HttpTools.js';
2
+ import { WINDOW } from '../Tools.js';
3
+
4
+ class Scope {
5
+ constructor() {
6
+ this.user = {};
7
+ }
8
+ setUser(userProps) {
9
+ this.user = __extends({}, userProps);
10
+ }
11
+ }
12
+ const scope = new Scope();
13
+ let payloadInterceptor = null;
14
+ let onPostSuccess = (data) => {
15
+ console.log('error stored: ', data);
16
+ };
17
+ let onPostError = (e, s) => {
18
+ console.log('failed to store error: ', s, e);
19
+ };
20
+ const captureError = (info, context) => {
21
+ let frames = processStackTrace(info.stack);
22
+ let event_id = crypto.randomUUID().replaceAll('-', '');
23
+ let payload = {
24
+ exception: {
25
+ values: [{
26
+ "type": info.type,
27
+ "value": info.message,
28
+ "stacktrace": { frames },
29
+ "mechanism": {
30
+ "handled": false,
31
+ "type": "instrument",
32
+ }
33
+ }]
34
+ },
35
+ level: "error",
36
+ event_id,
37
+ platform: "javascript",
38
+ timestamp: Date.now(),
39
+ environment: scope.environment,
40
+ release: scope.release,
41
+ request: {
42
+ url: WINDOW.location.href,
43
+ headers: {
44
+ "User-Agent": navigator.userAgent
45
+ }
46
+ },
47
+ "extra": {
48
+ "arguments": []
49
+ },
50
+ user: scope.user,
51
+ };
52
+ payload = payloadInterceptor ? payloadInterceptor(payload, context) : payload;
53
+ payload && fetch(scope.url, {
54
+ method: 'POST',
55
+ params: payload,
56
+ withCredentials: false,
57
+ onSuccess: onPostSuccess,
58
+ onError: onPostError
59
+ });
60
+ };
61
+ const processStackTrace = (stack) => {
62
+ if (!stack)
63
+ return [];
64
+ let lines = stack.split(/\n\s*/);
65
+ let frames = lines.map((line, j) => {
66
+ if (j === 0 || !line)
67
+ return null;
68
+ let filename;
69
+ let fn;
70
+ let colno;
71
+ let lineno;
72
+ let separator = ' ';
73
+ if (line.startsWith('at ')) {
74
+ line = line.substring(3);
75
+ }
76
+ else {
77
+ separator = '@';
78
+ }
79
+ let i;
80
+ if (line.endsWith(')')) {
81
+ i = line.lastIndexOf('(');
82
+ filename = line.substring(i + 1, __length(line) - 1);
83
+ i--;
84
+ }
85
+ else {
86
+ i = line.lastIndexOf(separator);
87
+ filename = line.substring(i + 1, __length(line));
88
+ }
89
+ fn = line.substring(0, i);
90
+ i = filename.lastIndexOf(':');
91
+ if (i !== -1) {
92
+ colno = parseInt(filename.substring(i + 1), 10);
93
+ filename = filename.substring(0, i);
94
+ }
95
+ i = filename.lastIndexOf(':');
96
+ if (i !== -1) {
97
+ lineno = parseInt(filename.substring(i + 1), 10);
98
+ filename = filename.substring(0, i);
99
+ }
100
+ return {
101
+ filename, 'function': fn || '?', lineno, colno,
102
+ };
103
+ });
104
+ if (!frames[__length(frames) - 1])
105
+ frames.pop();
106
+ frames.reverse();
107
+ if (!frames[__length(frames) - 1])
108
+ frames.pop();
109
+ return frames;
110
+ };
111
+ const initExceptionHandlers = () => {
112
+ let prevonerror = WINDOW.onerror;
113
+ WINDOW.onerror = (message, source, lineno, colno, error) => {
114
+ prevonerror && prevonerror(message, source, lineno, colno, error);
115
+ captureError({
116
+ message: error ? error.message : message,
117
+ source,
118
+ lineno,
119
+ colno,
120
+ stack: error ? error.stack : null,
121
+ error,
122
+ type: error ? error.name : 'Error',
123
+ });
124
+ };
125
+ WINDOW.onunhandledrejection = event => {
126
+ captureError({
127
+ message: event.reason.message || 'Unhandled promise rejection',
128
+ stack: event.reason.stack || null,
129
+ type: 'Error'
130
+ });
131
+ };
132
+ };
133
+ const init = (args) => {
134
+ scope.dsn = args.dsn;
135
+ scope.release = args.release;
136
+ scope.environment = args.environment;
137
+ scope.userAgent = navigator.userAgent;
138
+ let url = new URL(scope.dsn);
139
+ scope.url = url.origin + '/api' + url.pathname + '/store/?sentry_key=' + url.username;
140
+ initExceptionHandlers();
141
+ };
142
+ const captureException = (e, context) => {
143
+ if (e instanceof Error) {
144
+ captureError({
145
+ message: e.message,
146
+ stack: e.stack,
147
+ }, context);
148
+ }
149
+ else {
150
+ captureError({
151
+ message: e,
152
+ }, context);
153
+ }
154
+ };
155
+ const configureScope = (f) => {
156
+ f(scope);
157
+ };
158
+ const setPayloadInterceptor = (interceptor) => {
159
+ payloadInterceptor = interceptor;
160
+ };
161
+ const setOnPostSuccess = (onSuccess) => {
162
+ onPostSuccess = onSuccess;
163
+ };
164
+ const setOnErrorSuccess = (onError) => {
165
+ onPostError = onError;
166
+ };
167
+
168
+ export { captureException, configureScope, init, setOnErrorSuccess, setOnPostSuccess, setPayloadInterceptor };
169
+ //# sourceMappingURL=SimpleSentryClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SimpleSentryClient.js","sources":["../src/misc/SimpleSentryClient.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-ui-basics",
3
- "version": "0.0.224",
3
+ "version": "0.0.226",
4
4
  "description": "",
5
5
  "module": "index.js",
6
6
  "_main": "index.cjs.js",
@@ -167,8 +167,11 @@ class FilteredList<T extends string|number> extends PureComponent<FilteredListPr
167
167
  };
168
168
 
169
169
  updateScroll = (id) => {
170
- let child = this.elements[id];
171
- let container = this.el;
170
+ const child = this.elements[id];
171
+ if (!child)
172
+ return
173
+
174
+ const container = this.el;
172
175
  const scrollTop = container.getScroll();
173
176
  const height = container.getHeight();
174
177
  let isVisible = scrollTop <= child.offsetTop && scrollTop + height >= child.offsetTop + child.clientHeight;
package/src/index.js CHANGED
@@ -24,6 +24,7 @@ import Modal from "./Modal";
24
24
  import ModalMenu from "./ModalMenu";
25
25
  import Router from "./router";
26
26
  import Scrollable from "./Scrollable";
27
+ import * as SimpleSentryClient from "./misc/SimpleSentryClient";
27
28
  import Size from "./Size";
28
29
  import Snackbar from "./Snackbar";
29
30
  import SpinningProgress from "./SpinningProgress";
@@ -68,6 +69,7 @@ export {
68
69
  Router,
69
70
  Scrollable,
70
71
  ScrollableTable,
72
+ SimpleSentryClient,
71
73
  Size,
72
74
  Snackbar,
73
75
  SpinningProgress,
@@ -0,0 +1,237 @@
1
+ import {fetch} from '../HttpTools'
2
+ import {WINDOW} from "../Tools";
3
+
4
+ interface ErrorInfo {
5
+ message: Event | string
6
+ source?: string
7
+ lineno?: number
8
+ colno?: number
9
+ stack?: string
10
+ type?: string
11
+ error?: Error
12
+ }
13
+
14
+ interface Context {
15
+ extra: any
16
+ }
17
+
18
+ interface Frame {
19
+ filename: string,
20
+ function: string,
21
+ lineno: string,
22
+ colno: string,
23
+ }
24
+
25
+ interface User {
26
+ id?: string | number,
27
+ name?: string,
28
+ username?: string,
29
+ email?: string,
30
+ }
31
+
32
+ interface Request {
33
+ url: string,
34
+ headers: { [key: string]: string },
35
+ }
36
+
37
+ class Scope {
38
+ user: User = {}
39
+ dsn: string
40
+ release: string
41
+ environment: string
42
+ userAgent: string
43
+ url: string
44
+
45
+ setUser(userProps: User) {
46
+ this.user = {...userProps};
47
+ }
48
+ }
49
+
50
+ interface Payload {
51
+ level: string,
52
+ exception: any,
53
+ event_id: string,
54
+ platform: string,
55
+ timestamp: number,
56
+ environment: string,
57
+ release: string,
58
+ request: Request,
59
+ extra: any,
60
+ user: User,
61
+ }
62
+
63
+ type PayloadInterceptor = (payload: Payload, context: Context) => (Payload | null)
64
+
65
+ const scope = new Scope();
66
+ let payloadInterceptor: PayloadInterceptor = null
67
+ let onPostSuccess = (data) => {
68
+ console.log('error stored: ', data)
69
+ };
70
+ let onPostError = (e, s) => {
71
+ console.log('failed to store error: ', s, e)
72
+ };
73
+
74
+ const captureError = (info: ErrorInfo, context?: Context) => {
75
+ let frames = processStackTrace(info.stack)
76
+ let event_id = crypto.randomUUID().replaceAll('-', '');
77
+ let payload: Payload = {
78
+ exception: {
79
+ values: [{
80
+ "type": info.type,
81
+ "value": info.message,
82
+ "stacktrace": {frames},
83
+ "mechanism": {
84
+ "handled": false,
85
+ "type": "instrument",
86
+ }
87
+ }]
88
+ },
89
+ level: "error",
90
+ event_id,
91
+ platform: "javascript",
92
+ timestamp: Date.now(),
93
+ environment: scope.environment,
94
+ release: scope.release,
95
+ request: {
96
+ url: WINDOW.location.href,
97
+ headers: {
98
+ "User-Agent": navigator.userAgent
99
+ }
100
+ },
101
+ "extra": {
102
+ "arguments": []
103
+ },
104
+ user: scope.user,
105
+ }
106
+
107
+ payload = payloadInterceptor ? payloadInterceptor(payload, context) : payload
108
+ payload && fetch(scope.url, {
109
+ method: 'POST',
110
+ params: payload,
111
+ withCredentials: false,
112
+ onSuccess: onPostSuccess,
113
+ onError: onPostError
114
+ })
115
+ }
116
+
117
+ const processStackTrace = (stack: string): Frame[] => {
118
+ if (!stack)
119
+ return []
120
+
121
+ let lines = stack.split(/\n\s*/);
122
+ let frames = lines.map((line, j) => {
123
+ if (j === 0 || !line)
124
+ return null
125
+
126
+ let filename;
127
+ let fn;
128
+ let colno;
129
+ let lineno;
130
+ let separator = ' '
131
+
132
+ if (line.startsWith('at ')) {
133
+ line = line.substring(3);
134
+ } else {
135
+ separator = '@'
136
+ }
137
+
138
+ let i;
139
+ if (line.endsWith(')')) {
140
+ i = line.lastIndexOf('(');
141
+ filename = line.substring(i + 1, line.length - 1);
142
+ i--;
143
+ } else {
144
+ i = line.lastIndexOf(separator);
145
+ filename = line.substring(i + 1, line.length);
146
+ }
147
+ fn = line.substring(0, i);
148
+
149
+ i = filename.lastIndexOf(':');
150
+ if (i !== -1) {
151
+ colno = parseInt(filename.substring(i + 1), 10);
152
+ filename = filename.substring(0, i);
153
+ }
154
+ i = filename.lastIndexOf(':');
155
+ if (i !== -1) {
156
+ lineno = parseInt(filename.substring(i + 1), 10);
157
+ filename = filename.substring(0, i);
158
+ }
159
+ return {
160
+ filename, 'function': fn || '?', lineno, colno,
161
+ }
162
+ })
163
+ if (!frames[frames.length - 1])
164
+ frames.pop();
165
+ frames.reverse();
166
+ if (!frames[frames.length - 1])
167
+ frames.pop();
168
+ return frames;
169
+ }
170
+
171
+
172
+ const initExceptionHandlers = () => {
173
+ let prevonerror = WINDOW.onerror
174
+ WINDOW.onerror = (message, source, lineno, colno, error) => {
175
+ prevonerror && prevonerror(message, source, lineno, colno, error)
176
+ captureError({
177
+ message: error ? error.message : message,
178
+ source,
179
+ lineno,
180
+ colno,
181
+ stack: error ? error.stack : null,
182
+ error,
183
+ type: error ? error.name : 'Error',
184
+ });
185
+ };
186
+
187
+ WINDOW.onunhandledrejection = event => {
188
+ captureError({
189
+ message: event.reason.message || 'Unhandled promise rejection',
190
+ stack: event.reason.stack || null,
191
+ type: 'Error'
192
+ });
193
+ };
194
+ }
195
+
196
+ export const init = (args: {
197
+ dsn: string
198
+ release: string
199
+ environment: string
200
+ }) => {
201
+ scope.dsn = args.dsn
202
+ scope.release = args.release
203
+ scope.environment = args.environment
204
+ scope.userAgent = navigator.userAgent
205
+
206
+ let url = new URL(scope.dsn);
207
+ scope.url = url.origin + '/api' + url.pathname + '/store/?sentry_key=' + url.username;
208
+ initExceptionHandlers()
209
+ }
210
+
211
+ export const captureException = (e: Error | string, context: Context) => {
212
+ if (e instanceof Error) {
213
+ captureError({
214
+ message: e.message,
215
+ stack: e.stack,
216
+ }, context)
217
+ } else {
218
+ captureError({
219
+ message: e,
220
+ }, context)
221
+ }
222
+ }
223
+
224
+ export const configureScope = (f: (scope: Scope) => void) => {
225
+ f(scope)
226
+ }
227
+
228
+ export const setPayloadInterceptor = (interceptor: PayloadInterceptor) => {
229
+ payloadInterceptor = interceptor
230
+ }
231
+
232
+ export const setOnPostSuccess = (onSuccess) => {
233
+ onPostSuccess = onSuccess
234
+ }
235
+ export const setOnErrorSuccess = (onError) => {
236
+ onPostError = onError
237
+ }