@nexussdk/sdk 0.0.3 → 0.0.4
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 +40 -2
- package/dist/index.cjs +2 -1
- package/dist/index.d.mts +41 -45
- package/dist/index.d.ts +41 -45
- package/dist/index.global.js +4 -3
- package/dist/index.mjs +2 -1
- package/dist/react.cjs +2 -1
- package/dist/react.d.mts +111 -76
- package/dist/react.d.ts +111 -76
- package/dist/react.mjs +2 -1
- package/dist/vue.cjs +2 -0
- package/dist/vue.d.mts +234 -0
- package/dist/vue.d.ts +234 -0
- package/dist/vue.mjs +2 -0
- package/package.json +32 -10
package/dist/vue.d.mts
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import * as vue from 'vue';
|
|
2
|
+
import { InjectionKey, Plugin, Ref } from 'vue';
|
|
3
|
+
import { NexusFlagsClient, NexusFlagsOptions } from '@nexussdk/flags';
|
|
4
|
+
import { NexusTrackerClient, NexusTrackerOptions } from '@nexussdk/tracker';
|
|
5
|
+
import { UserContext, SamplingConfig, TransportPlugin, PerformanceVitalsOptions, SeverityLevel, Breadcrumb, NexusErrorInfo, FlagEvaluationResult } from '@nexussdk/contracts';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview Unified Nexus singleton facade wrapping Flags and Tracker clients.
|
|
9
|
+
* @module @nexus/sdk/nexus
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Dev server routing configuration.
|
|
14
|
+
*/
|
|
15
|
+
interface NexusDevServerOptions {
|
|
16
|
+
/** Enable local dev server ingestion mode. Auto-enabled in development if true. */
|
|
17
|
+
enabled?: boolean;
|
|
18
|
+
/** Port the dev server is listening on. Defaults to 4567. */
|
|
19
|
+
port?: number;
|
|
20
|
+
/** Host the dev server is bound to. Defaults to 'localhost'. */
|
|
21
|
+
host?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Unified initialization options for the Nexus SDK umbrella.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* Nexus.init({
|
|
28
|
+
* apiKey: 'pk_live_...',
|
|
29
|
+
* user: { id: 'usr_12345', country: 'VN' },
|
|
30
|
+
* environment: 'production',
|
|
31
|
+
* autoCapture: true,
|
|
32
|
+
* devServer: { enabled: process.env.NODE_ENV === 'development' },
|
|
33
|
+
* });
|
|
34
|
+
*/
|
|
35
|
+
interface NexusInitOptions {
|
|
36
|
+
/** Public API key. Resolved from env if omitted. */
|
|
37
|
+
apiKey?: string;
|
|
38
|
+
/** Base URL for all API calls. */
|
|
39
|
+
baseUrl?: string;
|
|
40
|
+
/** Initial user context for flag targeting and error attribution. */
|
|
41
|
+
user?: UserContext;
|
|
42
|
+
/** Target environment for telemetry routing. Defaults to 'production'. */
|
|
43
|
+
environment?: string;
|
|
44
|
+
/** Global tags attached to all telemetry events. */
|
|
45
|
+
tags?: Record<string, string>;
|
|
46
|
+
/** Toggle automated global error capture. Defaults to true. */
|
|
47
|
+
autoCapture?: boolean;
|
|
48
|
+
/** Client-side rate limiting and deduplication sampling options. */
|
|
49
|
+
sampling?: SamplingConfig;
|
|
50
|
+
/** Pluggable transport adapter ('fetch', 'console', 'localStorage', custom fn). */
|
|
51
|
+
transport?: TransportPlugin;
|
|
52
|
+
/** Web Vitals performance observer options, or true for default observation. */
|
|
53
|
+
vitals?: boolean | PerformanceVitalsOptions;
|
|
54
|
+
/** Local dev server auto-routing configuration. */
|
|
55
|
+
devServer?: NexusDevServerOptions;
|
|
56
|
+
/** Additional flags-specific options. */
|
|
57
|
+
flags?: Partial<NexusFlagsOptions>;
|
|
58
|
+
/** Additional tracker-specific options. */
|
|
59
|
+
tracker?: Partial<NexusTrackerOptions>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The Nexus singleton class — the primary unified entry point for the SDK.
|
|
63
|
+
*
|
|
64
|
+
* Provides access to both the feature flags client and the error tracker client.
|
|
65
|
+
* Initialize once, then use throughout your application.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* // Initialize (call once at app startup)
|
|
69
|
+
* Nexus.init({ apiKey: 'pk_live_...' });
|
|
70
|
+
*
|
|
71
|
+
* // Feature flags
|
|
72
|
+
* const showBanner = Nexus.isEnabled('promo_banner_v2', false);
|
|
73
|
+
*
|
|
74
|
+
* // Error tracking
|
|
75
|
+
* Nexus.captureError(new Error('Something went wrong'));
|
|
76
|
+
*
|
|
77
|
+
* // Update user context
|
|
78
|
+
* await Nexus.identify({ id: 'usr_12345', country: 'VN' });
|
|
79
|
+
*/
|
|
80
|
+
declare class Nexus {
|
|
81
|
+
private static instance;
|
|
82
|
+
private static vitalsCleanup;
|
|
83
|
+
/** The underlying feature flags client instance. */
|
|
84
|
+
readonly flags: NexusFlagsClient;
|
|
85
|
+
/** The underlying error tracker client instance. */
|
|
86
|
+
readonly tracker: NexusTrackerClient;
|
|
87
|
+
private constructor();
|
|
88
|
+
/**
|
|
89
|
+
* Initializes the Nexus SDK singleton.
|
|
90
|
+
* Must be called before any other SDK methods.
|
|
91
|
+
* Safe to call multiple times — returns existing instance after first init.
|
|
92
|
+
*
|
|
93
|
+
* @param options - SDK configuration options.
|
|
94
|
+
* @returns The initialized Nexus singleton instance.
|
|
95
|
+
*/
|
|
96
|
+
static init(options?: NexusInitOptions): Nexus;
|
|
97
|
+
/**
|
|
98
|
+
* Returns the current Nexus singleton instance.
|
|
99
|
+
*
|
|
100
|
+
* @returns The active Nexus instance.
|
|
101
|
+
* @throws {Error} If `Nexus.init()` has not been called yet.
|
|
102
|
+
*/
|
|
103
|
+
static getInstance(): Nexus;
|
|
104
|
+
/**
|
|
105
|
+
* Convenience method: Check if a feature flag is enabled.
|
|
106
|
+
*/
|
|
107
|
+
static isEnabled(key: string, defaultValue?: boolean): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Convenience method: Get a flag variant value.
|
|
110
|
+
*/
|
|
111
|
+
static getVariant<T = unknown>(key: string, variantKey: string, defaultValue?: T): T;
|
|
112
|
+
/**
|
|
113
|
+
* Convenience method: Capture an error manually.
|
|
114
|
+
*/
|
|
115
|
+
static captureError(error: unknown, extra?: Record<string, unknown>): void;
|
|
116
|
+
/**
|
|
117
|
+
* Convenience method: Capture an informational or warning message event.
|
|
118
|
+
*/
|
|
119
|
+
static captureMessage(message: string, level?: SeverityLevel, extra?: Record<string, unknown>): void;
|
|
120
|
+
/**
|
|
121
|
+
* Convenience method: Add a breadcrumb manually.
|
|
122
|
+
*/
|
|
123
|
+
static addBreadcrumb(breadcrumb: Breadcrumb): void;
|
|
124
|
+
/**
|
|
125
|
+
* Convenience method: Set extra contextual metadata.
|
|
126
|
+
*/
|
|
127
|
+
static setExtra(key: string, value: unknown): void;
|
|
128
|
+
/**
|
|
129
|
+
* Convenience method: Attach Web Vitals observer to tracker.
|
|
130
|
+
*/
|
|
131
|
+
static attachWebVitals(options?: PerformanceVitalsOptions): () => void;
|
|
132
|
+
/**
|
|
133
|
+
* Convenience method: Update user context for both flags and tracker.
|
|
134
|
+
*/
|
|
135
|
+
static identify(user: UserContext): Promise<void>;
|
|
136
|
+
/**
|
|
137
|
+
* Resets user context to anonymous state (e.g. on logout).
|
|
138
|
+
*/
|
|
139
|
+
static reset(): void;
|
|
140
|
+
/**
|
|
141
|
+
* Gracefully tears down both clients, closing SSE connections and flushing pending events.
|
|
142
|
+
*/
|
|
143
|
+
static destroy(): Promise<void>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface NexusVueContext {
|
|
147
|
+
flags: NexusFlagsClient;
|
|
148
|
+
tracker: NexusTrackerClient;
|
|
149
|
+
nexus: Nexus;
|
|
150
|
+
}
|
|
151
|
+
declare const NEXUS_KEY: InjectionKey<NexusVueContext>;
|
|
152
|
+
/**
|
|
153
|
+
* Vue 3 Plugin for initializing Nexus SDK and setting up global error handling.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* // main.ts
|
|
157
|
+
* import { createApp } from 'vue';
|
|
158
|
+
* import { NexusPlugin } from '@nexussdk/sdk/vue';
|
|
159
|
+
* import App from './App.vue';
|
|
160
|
+
*
|
|
161
|
+
* const app = createApp(App);
|
|
162
|
+
* app.use(NexusPlugin, {
|
|
163
|
+
* apiKey: 'pk_live_...',
|
|
164
|
+
* environment: 'production',
|
|
165
|
+
* });
|
|
166
|
+
* app.mount('#app');
|
|
167
|
+
*/
|
|
168
|
+
declare const NexusPlugin: Plugin;
|
|
169
|
+
/**
|
|
170
|
+
* Returns the Nexus context in a Vue component setup function.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* const { flags, tracker } = useNexus();
|
|
174
|
+
* tracker.captureMessage('Button clicked', 'info');
|
|
175
|
+
*/
|
|
176
|
+
declare function useNexus(): NexusVueContext;
|
|
177
|
+
interface UseFlagVueResult {
|
|
178
|
+
enabled: Ref<boolean>;
|
|
179
|
+
getVariant: <T = unknown>(variantKey: string, defaultValue?: T) => T;
|
|
180
|
+
result: Ref<FlagEvaluationResult | null>;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Vue 3 composable for subscribing to real-time feature flag changes.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* const { enabled, getVariant } = useFlag('promo_banner_v2');
|
|
187
|
+
*/
|
|
188
|
+
declare function useFlag(key: string, defaultEnabled?: boolean): UseFlagVueResult;
|
|
189
|
+
/**
|
|
190
|
+
* Vue 3 Error Boundary component using `onErrorCaptured`.
|
|
191
|
+
* Traps unhandled errors from child components, prevents crash propagation,
|
|
192
|
+
* and renders a customizable fallback via scoped slots or props.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* <!-- App.vue -->
|
|
196
|
+
* <NexusGuard>
|
|
197
|
+
* <template #fallback="{ error, errorId, reset }">
|
|
198
|
+
* <div class="custom-error">
|
|
199
|
+
* <h3>Error: {{ error.message }}</h3>
|
|
200
|
+
* <p>Ref: {{ errorId }}</p>
|
|
201
|
+
* <button @click="reset">Retry</button>
|
|
202
|
+
* </div>
|
|
203
|
+
* </template>
|
|
204
|
+
* <MyWidget />
|
|
205
|
+
* </NexusGuard>
|
|
206
|
+
*/
|
|
207
|
+
declare const NexusGuardVue: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
208
|
+
onError: {
|
|
209
|
+
type: () => (error: Error, info: NexusErrorInfo) => void;
|
|
210
|
+
default: undefined;
|
|
211
|
+
};
|
|
212
|
+
tags: {
|
|
213
|
+
type: () => Record<string, string>;
|
|
214
|
+
default: () => {};
|
|
215
|
+
};
|
|
216
|
+
}>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
217
|
+
[key: string]: any;
|
|
218
|
+
}> | vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
219
|
+
[key: string]: any;
|
|
220
|
+
}>[] | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
221
|
+
onError: {
|
|
222
|
+
type: () => (error: Error, info: NexusErrorInfo) => void;
|
|
223
|
+
default: undefined;
|
|
224
|
+
};
|
|
225
|
+
tags: {
|
|
226
|
+
type: () => Record<string, string>;
|
|
227
|
+
default: () => {};
|
|
228
|
+
};
|
|
229
|
+
}>> & Readonly<{}>, {
|
|
230
|
+
onError: (error: Error, info: NexusErrorInfo) => void;
|
|
231
|
+
tags: Record<string, string>;
|
|
232
|
+
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
233
|
+
|
|
234
|
+
export { NEXUS_KEY, NexusGuardVue, NexusPlugin, type NexusVueContext, type UseFlagVueResult, useFlag, useNexus };
|
package/dist/vue.d.ts
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import * as vue from 'vue';
|
|
2
|
+
import { InjectionKey, Plugin, Ref } from 'vue';
|
|
3
|
+
import { NexusFlagsClient, NexusFlagsOptions } from '@nexussdk/flags';
|
|
4
|
+
import { NexusTrackerClient, NexusTrackerOptions } from '@nexussdk/tracker';
|
|
5
|
+
import { UserContext, SamplingConfig, TransportPlugin, PerformanceVitalsOptions, SeverityLevel, Breadcrumb, NexusErrorInfo, FlagEvaluationResult } from '@nexussdk/contracts';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview Unified Nexus singleton facade wrapping Flags and Tracker clients.
|
|
9
|
+
* @module @nexus/sdk/nexus
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Dev server routing configuration.
|
|
14
|
+
*/
|
|
15
|
+
interface NexusDevServerOptions {
|
|
16
|
+
/** Enable local dev server ingestion mode. Auto-enabled in development if true. */
|
|
17
|
+
enabled?: boolean;
|
|
18
|
+
/** Port the dev server is listening on. Defaults to 4567. */
|
|
19
|
+
port?: number;
|
|
20
|
+
/** Host the dev server is bound to. Defaults to 'localhost'. */
|
|
21
|
+
host?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Unified initialization options for the Nexus SDK umbrella.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* Nexus.init({
|
|
28
|
+
* apiKey: 'pk_live_...',
|
|
29
|
+
* user: { id: 'usr_12345', country: 'VN' },
|
|
30
|
+
* environment: 'production',
|
|
31
|
+
* autoCapture: true,
|
|
32
|
+
* devServer: { enabled: process.env.NODE_ENV === 'development' },
|
|
33
|
+
* });
|
|
34
|
+
*/
|
|
35
|
+
interface NexusInitOptions {
|
|
36
|
+
/** Public API key. Resolved from env if omitted. */
|
|
37
|
+
apiKey?: string;
|
|
38
|
+
/** Base URL for all API calls. */
|
|
39
|
+
baseUrl?: string;
|
|
40
|
+
/** Initial user context for flag targeting and error attribution. */
|
|
41
|
+
user?: UserContext;
|
|
42
|
+
/** Target environment for telemetry routing. Defaults to 'production'. */
|
|
43
|
+
environment?: string;
|
|
44
|
+
/** Global tags attached to all telemetry events. */
|
|
45
|
+
tags?: Record<string, string>;
|
|
46
|
+
/** Toggle automated global error capture. Defaults to true. */
|
|
47
|
+
autoCapture?: boolean;
|
|
48
|
+
/** Client-side rate limiting and deduplication sampling options. */
|
|
49
|
+
sampling?: SamplingConfig;
|
|
50
|
+
/** Pluggable transport adapter ('fetch', 'console', 'localStorage', custom fn). */
|
|
51
|
+
transport?: TransportPlugin;
|
|
52
|
+
/** Web Vitals performance observer options, or true for default observation. */
|
|
53
|
+
vitals?: boolean | PerformanceVitalsOptions;
|
|
54
|
+
/** Local dev server auto-routing configuration. */
|
|
55
|
+
devServer?: NexusDevServerOptions;
|
|
56
|
+
/** Additional flags-specific options. */
|
|
57
|
+
flags?: Partial<NexusFlagsOptions>;
|
|
58
|
+
/** Additional tracker-specific options. */
|
|
59
|
+
tracker?: Partial<NexusTrackerOptions>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The Nexus singleton class — the primary unified entry point for the SDK.
|
|
63
|
+
*
|
|
64
|
+
* Provides access to both the feature flags client and the error tracker client.
|
|
65
|
+
* Initialize once, then use throughout your application.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* // Initialize (call once at app startup)
|
|
69
|
+
* Nexus.init({ apiKey: 'pk_live_...' });
|
|
70
|
+
*
|
|
71
|
+
* // Feature flags
|
|
72
|
+
* const showBanner = Nexus.isEnabled('promo_banner_v2', false);
|
|
73
|
+
*
|
|
74
|
+
* // Error tracking
|
|
75
|
+
* Nexus.captureError(new Error('Something went wrong'));
|
|
76
|
+
*
|
|
77
|
+
* // Update user context
|
|
78
|
+
* await Nexus.identify({ id: 'usr_12345', country: 'VN' });
|
|
79
|
+
*/
|
|
80
|
+
declare class Nexus {
|
|
81
|
+
private static instance;
|
|
82
|
+
private static vitalsCleanup;
|
|
83
|
+
/** The underlying feature flags client instance. */
|
|
84
|
+
readonly flags: NexusFlagsClient;
|
|
85
|
+
/** The underlying error tracker client instance. */
|
|
86
|
+
readonly tracker: NexusTrackerClient;
|
|
87
|
+
private constructor();
|
|
88
|
+
/**
|
|
89
|
+
* Initializes the Nexus SDK singleton.
|
|
90
|
+
* Must be called before any other SDK methods.
|
|
91
|
+
* Safe to call multiple times — returns existing instance after first init.
|
|
92
|
+
*
|
|
93
|
+
* @param options - SDK configuration options.
|
|
94
|
+
* @returns The initialized Nexus singleton instance.
|
|
95
|
+
*/
|
|
96
|
+
static init(options?: NexusInitOptions): Nexus;
|
|
97
|
+
/**
|
|
98
|
+
* Returns the current Nexus singleton instance.
|
|
99
|
+
*
|
|
100
|
+
* @returns The active Nexus instance.
|
|
101
|
+
* @throws {Error} If `Nexus.init()` has not been called yet.
|
|
102
|
+
*/
|
|
103
|
+
static getInstance(): Nexus;
|
|
104
|
+
/**
|
|
105
|
+
* Convenience method: Check if a feature flag is enabled.
|
|
106
|
+
*/
|
|
107
|
+
static isEnabled(key: string, defaultValue?: boolean): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Convenience method: Get a flag variant value.
|
|
110
|
+
*/
|
|
111
|
+
static getVariant<T = unknown>(key: string, variantKey: string, defaultValue?: T): T;
|
|
112
|
+
/**
|
|
113
|
+
* Convenience method: Capture an error manually.
|
|
114
|
+
*/
|
|
115
|
+
static captureError(error: unknown, extra?: Record<string, unknown>): void;
|
|
116
|
+
/**
|
|
117
|
+
* Convenience method: Capture an informational or warning message event.
|
|
118
|
+
*/
|
|
119
|
+
static captureMessage(message: string, level?: SeverityLevel, extra?: Record<string, unknown>): void;
|
|
120
|
+
/**
|
|
121
|
+
* Convenience method: Add a breadcrumb manually.
|
|
122
|
+
*/
|
|
123
|
+
static addBreadcrumb(breadcrumb: Breadcrumb): void;
|
|
124
|
+
/**
|
|
125
|
+
* Convenience method: Set extra contextual metadata.
|
|
126
|
+
*/
|
|
127
|
+
static setExtra(key: string, value: unknown): void;
|
|
128
|
+
/**
|
|
129
|
+
* Convenience method: Attach Web Vitals observer to tracker.
|
|
130
|
+
*/
|
|
131
|
+
static attachWebVitals(options?: PerformanceVitalsOptions): () => void;
|
|
132
|
+
/**
|
|
133
|
+
* Convenience method: Update user context for both flags and tracker.
|
|
134
|
+
*/
|
|
135
|
+
static identify(user: UserContext): Promise<void>;
|
|
136
|
+
/**
|
|
137
|
+
* Resets user context to anonymous state (e.g. on logout).
|
|
138
|
+
*/
|
|
139
|
+
static reset(): void;
|
|
140
|
+
/**
|
|
141
|
+
* Gracefully tears down both clients, closing SSE connections and flushing pending events.
|
|
142
|
+
*/
|
|
143
|
+
static destroy(): Promise<void>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface NexusVueContext {
|
|
147
|
+
flags: NexusFlagsClient;
|
|
148
|
+
tracker: NexusTrackerClient;
|
|
149
|
+
nexus: Nexus;
|
|
150
|
+
}
|
|
151
|
+
declare const NEXUS_KEY: InjectionKey<NexusVueContext>;
|
|
152
|
+
/**
|
|
153
|
+
* Vue 3 Plugin for initializing Nexus SDK and setting up global error handling.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* // main.ts
|
|
157
|
+
* import { createApp } from 'vue';
|
|
158
|
+
* import { NexusPlugin } from '@nexussdk/sdk/vue';
|
|
159
|
+
* import App from './App.vue';
|
|
160
|
+
*
|
|
161
|
+
* const app = createApp(App);
|
|
162
|
+
* app.use(NexusPlugin, {
|
|
163
|
+
* apiKey: 'pk_live_...',
|
|
164
|
+
* environment: 'production',
|
|
165
|
+
* });
|
|
166
|
+
* app.mount('#app');
|
|
167
|
+
*/
|
|
168
|
+
declare const NexusPlugin: Plugin;
|
|
169
|
+
/**
|
|
170
|
+
* Returns the Nexus context in a Vue component setup function.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* const { flags, tracker } = useNexus();
|
|
174
|
+
* tracker.captureMessage('Button clicked', 'info');
|
|
175
|
+
*/
|
|
176
|
+
declare function useNexus(): NexusVueContext;
|
|
177
|
+
interface UseFlagVueResult {
|
|
178
|
+
enabled: Ref<boolean>;
|
|
179
|
+
getVariant: <T = unknown>(variantKey: string, defaultValue?: T) => T;
|
|
180
|
+
result: Ref<FlagEvaluationResult | null>;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Vue 3 composable for subscribing to real-time feature flag changes.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* const { enabled, getVariant } = useFlag('promo_banner_v2');
|
|
187
|
+
*/
|
|
188
|
+
declare function useFlag(key: string, defaultEnabled?: boolean): UseFlagVueResult;
|
|
189
|
+
/**
|
|
190
|
+
* Vue 3 Error Boundary component using `onErrorCaptured`.
|
|
191
|
+
* Traps unhandled errors from child components, prevents crash propagation,
|
|
192
|
+
* and renders a customizable fallback via scoped slots or props.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* <!-- App.vue -->
|
|
196
|
+
* <NexusGuard>
|
|
197
|
+
* <template #fallback="{ error, errorId, reset }">
|
|
198
|
+
* <div class="custom-error">
|
|
199
|
+
* <h3>Error: {{ error.message }}</h3>
|
|
200
|
+
* <p>Ref: {{ errorId }}</p>
|
|
201
|
+
* <button @click="reset">Retry</button>
|
|
202
|
+
* </div>
|
|
203
|
+
* </template>
|
|
204
|
+
* <MyWidget />
|
|
205
|
+
* </NexusGuard>
|
|
206
|
+
*/
|
|
207
|
+
declare const NexusGuardVue: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
208
|
+
onError: {
|
|
209
|
+
type: () => (error: Error, info: NexusErrorInfo) => void;
|
|
210
|
+
default: undefined;
|
|
211
|
+
};
|
|
212
|
+
tags: {
|
|
213
|
+
type: () => Record<string, string>;
|
|
214
|
+
default: () => {};
|
|
215
|
+
};
|
|
216
|
+
}>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
217
|
+
[key: string]: any;
|
|
218
|
+
}> | vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
219
|
+
[key: string]: any;
|
|
220
|
+
}>[] | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
221
|
+
onError: {
|
|
222
|
+
type: () => (error: Error, info: NexusErrorInfo) => void;
|
|
223
|
+
default: undefined;
|
|
224
|
+
};
|
|
225
|
+
tags: {
|
|
226
|
+
type: () => Record<string, string>;
|
|
227
|
+
default: () => {};
|
|
228
|
+
};
|
|
229
|
+
}>> & Readonly<{}>, {
|
|
230
|
+
onError: (error: Error, info: NexusErrorInfo) => void;
|
|
231
|
+
tags: Record<string, string>;
|
|
232
|
+
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
233
|
+
|
|
234
|
+
export { NEXUS_KEY, NexusGuardVue, NexusPlugin, type NexusVueContext, type UseFlagVueResult, useFlag, useNexus };
|
package/dist/vue.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {defineComponent,ref,shallowRef,onErrorCaptured,h,inject,onUnmounted}from'vue';import {NexusFlagsClient}from'@nexussdk/flags';import {parseStackTrace,computeFingerprint,NexusTrackerClient,attachWebVitals}from'@nexussdk/tracker';var p=class e{static instance=null;static vitalsCleanup=null;flags;tracker;constructor(t={}){let{apiKey:n,baseUrl:r,user:o,environment:a,tags:s,autoCapture:i,sampling:f,transport:x,vitals:l,devServer:c,flags:g,tracker:C}=t;this.flags=new NexusFlagsClient({apiKey:n,baseUrl:r,user:o,...g});let m=r,I=x;if(c?.enabled){let d=c.port??4567;m=`http://${c.host??"localhost"}:${d}`;}if(this.tracker=new NexusTrackerClient({apiKey:n,baseUrl:m,environment:a,tags:s,autoCapture:i,sampling:f,transport:I,...C}),l){let d=typeof l=="object"?l:{};e.vitalsCleanup=attachWebVitals(this.tracker,d);}}static init(t={}){return e.instance||(e.instance=new e(t)),e.instance}static getInstance(){if(!e.instance)throw new Error('[Nexus SDK] Not initialized. Call Nexus.init({ apiKey: "..." }) first.');return e.instance}static isEnabled(t,n=false){return e.getInstance().flags.isEnabled(t,n)}static getVariant(t,n,r){return e.getInstance().flags.getVariant(t,n,r)}static captureError(t,n){e.getInstance().tracker.captureError(t,n);}static captureMessage(t,n="info",r){e.getInstance().tracker.captureMessage(t,n,r);}static addBreadcrumb(t){e.getInstance().tracker.addBreadcrumb(t);}static setExtra(t,n){e.getInstance().tracker.setExtra(t,n);}static attachWebVitals(t){return attachWebVitals(e.getInstance().tracker,t)}static async identify(t){let n=e.getInstance();n.tracker.setUser(t),await n.flags.identify(t);}static reset(){let t=e.getInstance();t.tracker.setUser(null),t.flags.reset();}static async destroy(){e.vitalsCleanup&&(e.vitalsCleanup(),e.vitalsCleanup=null),e.instance&&(await e.instance.tracker.flush(),e.instance.tracker.destroy(),e.instance.flags.destroy(),e.instance=null);}};var y=Symbol("NexusSDK"),H={install(e,t={}){let n=p.init(t),r={flags:n.flags,tracker:n.tracker,nexus:n};e.provide(y,r);let o=e.config.errorHandler;e.config.errorHandler=(a,s,i)=>{n.tracker.captureError(a,{componentStack:i,tags:{framework:"vue3",component:s?.$options?.name||"AnonymousComponent"}}),o&&o(a,s,i);},e.component("NexusGuard",R);}};function N(){let e=inject(y);if(e)return e;let t=p.getInstance();return {flags:t.flags,tracker:t.tracker,nexus:t}}function A(e,t=false){let{flags:n}=N(),r=ref(n.isEnabled(e,t)),o=shallowRef(null),a=n.onFlagChange(e,s=>{r.value=s.enabled,o.value=s;});return onUnmounted(()=>{a();}),{enabled:r,getVariant:(s,i)=>n.getVariant(e,s,i),result:o}}var R=defineComponent({name:"NexusGuard",props:{onError:{type:Function,default:void 0},tags:{type:Object,default:()=>({})}},setup(e,{slots:t}){let n=ref(false),r=shallowRef(null),o=()=>{n.value=false,r.value=null;};return onErrorCaptured((a,s,i)=>{let f=parseStackTrace(a.stack),l=`NX-${computeFingerprint(a.name,a.message,f[0]).replace(/^fp_/,"").slice(0,8).toUpperCase()}`,c={error:a,errorId:l,componentStack:i,reset:o};n.value=true,r.value=c;try{let{tracker:g}=N();g.captureError(a,{componentStack:i,tags:{...e.tags,guardErrorId:l,framework:"vue3",component:s?.$options?.name||"AnonymousComponent"}});}catch{}if(e.onError)try{e.onError(a,c);}catch{}return false}),()=>n.value&&r.value?t.fallback?t.fallback(r.value):h("div",{role:"alert",style:{padding:"16px 20px",margin:"12px 0",borderRadius:"8px",backgroundColor:"#1f1315",border:"1px solid #7f1d1d",color:"#fca5a5",fontFamily:"-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif",fontSize:"14px"}},[h("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:"8px"}},[h("strong",{style:{color:"#ef4444"}},"Vue Component Crash Protected"),h("span",{style:{fontFamily:"monospace",fontSize:"12px",background:"#450a0a",padding:"2px 8px",borderRadius:"4px"}},r.value.errorId)]),h("p",{style:{margin:"0 0 12px 0",color:"#fecaca"}},r.value.error.message),h("button",{type:"button",onClick:o,style:{background:"#b91c1c",border:"none",color:"#fff",padding:"6px 14px",borderRadius:"6px",fontSize:"13px",cursor:"pointer",fontWeight:"500"}},"Retry Component")]):t.default?t.default():null}});
|
|
2
|
+
export{y as NEXUS_KEY,R as NexusGuardVue,H as NexusPlugin,A as useFlag,N as useNexus};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexussdk/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -21,17 +21,27 @@
|
|
|
21
21
|
"directory": "packages/sdk"
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/Huynhdung295/NexusSDK#readme",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/Huynhdung295/NexusSDK/issues"
|
|
26
|
+
},
|
|
24
27
|
"keywords": [
|
|
25
28
|
"nexus",
|
|
26
29
|
"nexussdk",
|
|
27
30
|
"feature-flags",
|
|
28
31
|
"feature-management",
|
|
32
|
+
"remote-config",
|
|
29
33
|
"telemetry",
|
|
30
34
|
"error-tracking",
|
|
31
35
|
"error-monitoring",
|
|
36
|
+
"error-boundary",
|
|
37
|
+
"web-vitals",
|
|
38
|
+
"pii-sanitizer",
|
|
32
39
|
"react",
|
|
40
|
+
"vue",
|
|
33
41
|
"nextjs",
|
|
34
|
-
"
|
|
42
|
+
"nuxt",
|
|
43
|
+
"sdk",
|
|
44
|
+
"zero-dependencies"
|
|
35
45
|
],
|
|
36
46
|
"files": [
|
|
37
47
|
"dist",
|
|
@@ -50,28 +60,40 @@
|
|
|
50
60
|
"types": "./dist/react.d.ts",
|
|
51
61
|
"import": "./dist/react.mjs",
|
|
52
62
|
"require": "./dist/react.cjs"
|
|
63
|
+
},
|
|
64
|
+
"./vue": {
|
|
65
|
+
"types": "./dist/vue.d.ts",
|
|
66
|
+
"import": "./dist/vue.mjs",
|
|
67
|
+
"require": "./dist/vue.cjs"
|
|
53
68
|
}
|
|
54
69
|
},
|
|
55
70
|
"dependencies": {
|
|
56
|
-
"@nexussdk/contracts": "0.0.
|
|
57
|
-
"@nexussdk/core": "0.0.
|
|
58
|
-
"@nexussdk/flags": "0.0.
|
|
59
|
-
"@nexussdk/tracker": "0.0.
|
|
71
|
+
"@nexussdk/contracts": "0.0.4",
|
|
72
|
+
"@nexussdk/core": "0.0.4",
|
|
73
|
+
"@nexussdk/flags": "0.0.4",
|
|
74
|
+
"@nexussdk/tracker": "0.0.4"
|
|
60
75
|
},
|
|
61
76
|
"peerDependencies": {
|
|
62
|
-
"react": ">=18.0.0"
|
|
77
|
+
"react": ">=18.0.0",
|
|
78
|
+
"vue": ">=3.0.0"
|
|
63
79
|
},
|
|
64
80
|
"peerDependenciesMeta": {
|
|
65
81
|
"react": {
|
|
66
82
|
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"vue": {
|
|
85
|
+
"optional": true
|
|
67
86
|
}
|
|
68
87
|
},
|
|
69
88
|
"devDependencies": {
|
|
70
|
-
"@types/react": "^
|
|
71
|
-
"react": "^
|
|
89
|
+
"@types/react": "^19.0.0",
|
|
90
|
+
"@types/react-dom": "^19.0.0",
|
|
91
|
+
"react": "^19.0.0",
|
|
92
|
+
"react-dom": "^19.0.0",
|
|
93
|
+
"rimraf": "^5.0.5",
|
|
72
94
|
"tsup": "^8.0.2",
|
|
73
95
|
"typescript": "^5.4.5",
|
|
74
|
-
"
|
|
96
|
+
"vue": "^3.5.42"
|
|
75
97
|
},
|
|
76
98
|
"scripts": {
|
|
77
99
|
"build": "tsup",
|