@nexushub/client 0.4.1 → 0.4.3
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/dist/content/local-cache-client.cjs +29 -4
- package/dist/content/local-cache-server.cjs +61 -26
- package/dist/index.cjs +314 -403
- package/dist/index.d.cts +1 -39
- package/dist/index.d.ts +1 -39
- package/dist/index.js +201 -337
- package/dist/local-cache-client-I6UYVJJV.js +59 -0
- package/dist/local-cache-client-IGAL7SZ6.cjs +59 -0
- package/dist/local-cache-server-6DXQJFCQ.cjs +114 -0
- package/dist/local-cache-server-DBJWR7HD.js +114 -0
- package/dist/react.cjs +2624 -0
- package/dist/react.d.cts +349 -0
- package/dist/react.d.ts +349 -0
- package/dist/react.js +2624 -0
- package/package.json +16 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import React from 'react';
|
|
3
1
|
import { I as ILocalCache } from './cache-types-B39iNHfE.cjs';
|
|
4
2
|
|
|
5
3
|
interface MinimalNexusConfig {
|
|
@@ -278,36 +276,6 @@ declare class NexusClient {
|
|
|
278
276
|
declare const nexus: NexusClient;
|
|
279
277
|
declare const createNexusClient: (config: Partial<NexusConfig>) => NexusClient;
|
|
280
278
|
|
|
281
|
-
interface NexusProviderProps {
|
|
282
|
-
children: React.ReactNode;
|
|
283
|
-
projectId?: string;
|
|
284
|
-
disableAnalytics?: boolean;
|
|
285
|
-
hasConsent?: boolean;
|
|
286
|
-
enableLiveFeed?: boolean;
|
|
287
|
-
onLiveEvent?: (event: LiveAnalyticsEvent) => void;
|
|
288
|
-
}
|
|
289
|
-
interface LiveAnalyticsEvent {
|
|
290
|
-
eventType: string;
|
|
291
|
-
projectId: string;
|
|
292
|
-
sessionId: string;
|
|
293
|
-
visitorId: string;
|
|
294
|
-
userId?: string;
|
|
295
|
-
data: {
|
|
296
|
-
event_id: string;
|
|
297
|
-
event_name?: string;
|
|
298
|
-
url: string;
|
|
299
|
-
timestamp: string;
|
|
300
|
-
geo?: Record<string, any>;
|
|
301
|
-
device?: Record<string, any>;
|
|
302
|
-
performance?: Record<string, any>;
|
|
303
|
-
ecommerce?: Record<string, any>;
|
|
304
|
-
};
|
|
305
|
-
timestamp: string;
|
|
306
|
-
sequence: number;
|
|
307
|
-
}
|
|
308
|
-
declare const NexusProvider: ({ children, projectId, disableAnalytics, hasConsent, enableLiveFeed, onLiveEvent, }: NexusProviderProps) => react_jsx_runtime.JSX.Element;
|
|
309
|
-
declare const useNexus: () => NexusClient;
|
|
310
|
-
|
|
311
279
|
interface SiteUser {
|
|
312
280
|
id: string;
|
|
313
281
|
email: string;
|
|
@@ -352,12 +320,6 @@ interface AuthContextType extends AuthState {
|
|
|
352
320
|
requestPasswordReset: (email: string) => Promise<void>;
|
|
353
321
|
}
|
|
354
322
|
|
|
355
|
-
declare const AuthProvider: ({ children, config, }: {
|
|
356
|
-
children: React.ReactNode;
|
|
357
|
-
config: NexusConfig;
|
|
358
|
-
}) => react_jsx_runtime.JSX.Element;
|
|
359
|
-
declare const useNexusAuth: () => AuthContextType;
|
|
360
|
-
|
|
361
323
|
/**
|
|
362
324
|
* NexusHub Shared Cache Implementations
|
|
363
325
|
*
|
|
@@ -435,4 +397,4 @@ declare class LocalCacheProxy implements ILocalCache {
|
|
|
435
397
|
|
|
436
398
|
declare const VERSION = "0.0.1";
|
|
437
399
|
|
|
438
|
-
export { AnalyticsEngine, type AuthContextType, type AuthError,
|
|
400
|
+
export { AnalyticsEngine, type AuthContextType, type AuthError, type AuthState, BrowserCache, type CacheEntry, type CacheMetadata, CacheTags, type CollectionQuery, type CollectionResponse, ContentEngine, type ContentResponse, DEFAULT_ANALYTICS_URL, DEFAULT_API_URL, type ErrorResponse, LOCAL_NEST_URL, LOCAL_RUST_URL, LocalCacheProxy as LocalCache, type LoginCredentials, MemoryCache, type MinimalNexusConfig, NexusClient, type NexusConfig, type RegisterCredentials, type SiteUser, VERSION, createNexusClient, getEnvConfig, getFullConfig, mergeConfigs, nexus, validateConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import React from 'react';
|
|
3
1
|
import { I as ILocalCache } from './cache-types-B39iNHfE.js';
|
|
4
2
|
|
|
5
3
|
interface MinimalNexusConfig {
|
|
@@ -278,36 +276,6 @@ declare class NexusClient {
|
|
|
278
276
|
declare const nexus: NexusClient;
|
|
279
277
|
declare const createNexusClient: (config: Partial<NexusConfig>) => NexusClient;
|
|
280
278
|
|
|
281
|
-
interface NexusProviderProps {
|
|
282
|
-
children: React.ReactNode;
|
|
283
|
-
projectId?: string;
|
|
284
|
-
disableAnalytics?: boolean;
|
|
285
|
-
hasConsent?: boolean;
|
|
286
|
-
enableLiveFeed?: boolean;
|
|
287
|
-
onLiveEvent?: (event: LiveAnalyticsEvent) => void;
|
|
288
|
-
}
|
|
289
|
-
interface LiveAnalyticsEvent {
|
|
290
|
-
eventType: string;
|
|
291
|
-
projectId: string;
|
|
292
|
-
sessionId: string;
|
|
293
|
-
visitorId: string;
|
|
294
|
-
userId?: string;
|
|
295
|
-
data: {
|
|
296
|
-
event_id: string;
|
|
297
|
-
event_name?: string;
|
|
298
|
-
url: string;
|
|
299
|
-
timestamp: string;
|
|
300
|
-
geo?: Record<string, any>;
|
|
301
|
-
device?: Record<string, any>;
|
|
302
|
-
performance?: Record<string, any>;
|
|
303
|
-
ecommerce?: Record<string, any>;
|
|
304
|
-
};
|
|
305
|
-
timestamp: string;
|
|
306
|
-
sequence: number;
|
|
307
|
-
}
|
|
308
|
-
declare const NexusProvider: ({ children, projectId, disableAnalytics, hasConsent, enableLiveFeed, onLiveEvent, }: NexusProviderProps) => react_jsx_runtime.JSX.Element;
|
|
309
|
-
declare const useNexus: () => NexusClient;
|
|
310
|
-
|
|
311
279
|
interface SiteUser {
|
|
312
280
|
id: string;
|
|
313
281
|
email: string;
|
|
@@ -352,12 +320,6 @@ interface AuthContextType extends AuthState {
|
|
|
352
320
|
requestPasswordReset: (email: string) => Promise<void>;
|
|
353
321
|
}
|
|
354
322
|
|
|
355
|
-
declare const AuthProvider: ({ children, config, }: {
|
|
356
|
-
children: React.ReactNode;
|
|
357
|
-
config: NexusConfig;
|
|
358
|
-
}) => react_jsx_runtime.JSX.Element;
|
|
359
|
-
declare const useNexusAuth: () => AuthContextType;
|
|
360
|
-
|
|
361
323
|
/**
|
|
362
324
|
* NexusHub Shared Cache Implementations
|
|
363
325
|
*
|
|
@@ -435,4 +397,4 @@ declare class LocalCacheProxy implements ILocalCache {
|
|
|
435
397
|
|
|
436
398
|
declare const VERSION = "0.0.1";
|
|
437
399
|
|
|
438
|
-
export { AnalyticsEngine, type AuthContextType, type AuthError,
|
|
400
|
+
export { AnalyticsEngine, type AuthContextType, type AuthError, type AuthState, BrowserCache, type CacheEntry, type CacheMetadata, CacheTags, type CollectionQuery, type CollectionResponse, ContentEngine, type ContentResponse, DEFAULT_ANALYTICS_URL, DEFAULT_API_URL, type ErrorResponse, LOCAL_NEST_URL, LOCAL_RUST_URL, LocalCacheProxy as LocalCache, type LoginCredentials, MemoryCache, type MinimalNexusConfig, NexusClient, type NexusConfig, type RegisterCredentials, type SiteUser, VERSION, createNexusClient, getEnvConfig, getFullConfig, mergeConfigs, nexus, validateConfig };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,202 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
+
};
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/content/local-cache-server.ts
|
|
12
|
+
var local_cache_server_exports = {};
|
|
13
|
+
__export(local_cache_server_exports, {
|
|
14
|
+
LocalCache: () => LocalCache
|
|
15
|
+
});
|
|
16
|
+
import fs from "fs";
|
|
17
|
+
import path from "path";
|
|
18
|
+
var LocalCache;
|
|
19
|
+
var init_local_cache_server = __esm({
|
|
20
|
+
"src/content/local-cache-server.ts"() {
|
|
21
|
+
"use strict";
|
|
22
|
+
LocalCache = class {
|
|
23
|
+
constructor(customPath) {
|
|
24
|
+
this.baseDir = customPath || ".nexus/local";
|
|
25
|
+
}
|
|
26
|
+
isLoaded() {
|
|
27
|
+
return fs.existsSync(path.resolve(process.cwd(), this.baseDir));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Retrieve a specific page directly from its file.
|
|
31
|
+
*/
|
|
32
|
+
async getPage(slug) {
|
|
33
|
+
try {
|
|
34
|
+
const filePath = path.resolve(
|
|
35
|
+
process.cwd(),
|
|
36
|
+
this.baseDir,
|
|
37
|
+
"pages",
|
|
38
|
+
`${slug}.json`
|
|
39
|
+
);
|
|
40
|
+
if (fs.existsSync(filePath)) {
|
|
41
|
+
const fileContent = fs.readFileSync(filePath, "utf-8");
|
|
42
|
+
const pageData = JSON.parse(fileContent);
|
|
43
|
+
return pageData.data !== void 0 ? pageData.data : pageData;
|
|
44
|
+
}
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (process.env.NODE_ENV === "development") {
|
|
47
|
+
console.warn(
|
|
48
|
+
`\u26A0\uFE0F NexusHub: Failed to load local page '${slug}':`,
|
|
49
|
+
error
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Retrieve an entire collection from its specific collection file.
|
|
57
|
+
*/
|
|
58
|
+
async getCollection(collectionId) {
|
|
59
|
+
try {
|
|
60
|
+
const filePath = path.resolve(
|
|
61
|
+
process.cwd(),
|
|
62
|
+
this.baseDir,
|
|
63
|
+
"collections",
|
|
64
|
+
`${collectionId}.json`
|
|
65
|
+
);
|
|
66
|
+
if (fs.existsSync(filePath)) {
|
|
67
|
+
const fileContent = fs.readFileSync(filePath, "utf-8");
|
|
68
|
+
return JSON.parse(fileContent);
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (process.env.NODE_ENV === "development") {
|
|
72
|
+
console.warn(
|
|
73
|
+
`\u26A0\uFE0F NexusHub: Failed to load local collection '${collectionId}':`,
|
|
74
|
+
error
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Retrieve global settings from its file.
|
|
82
|
+
*/
|
|
83
|
+
async getGlobals() {
|
|
84
|
+
try {
|
|
85
|
+
const filePath = path.resolve(
|
|
86
|
+
process.cwd(),
|
|
87
|
+
this.baseDir,
|
|
88
|
+
"globals.json"
|
|
89
|
+
);
|
|
90
|
+
if (fs.existsSync(filePath)) {
|
|
91
|
+
const fileContent = fs.readFileSync(filePath, "utf-8");
|
|
92
|
+
return JSON.parse(fileContent);
|
|
93
|
+
}
|
|
94
|
+
} catch {
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Returns a merged JSON of the entire workspace structure (for dev analytics/inspectors)
|
|
100
|
+
*/
|
|
101
|
+
async getAllData() {
|
|
102
|
+
const pages = {};
|
|
103
|
+
const collections = {};
|
|
104
|
+
let globals = {};
|
|
105
|
+
try {
|
|
106
|
+
const pagesDir = path.resolve(process.cwd(), this.baseDir, "pages");
|
|
107
|
+
if (fs.existsSync(pagesDir)) {
|
|
108
|
+
for (const file of fs.readdirSync(pagesDir)) {
|
|
109
|
+
if (file.endsWith(".json")) {
|
|
110
|
+
const slug = path.basename(file, ".json");
|
|
111
|
+
pages[slug] = await this.getPage(slug);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const colsDir = path.resolve(process.cwd(), this.baseDir, "collections");
|
|
116
|
+
if (fs.existsSync(colsDir)) {
|
|
117
|
+
for (const file of fs.readdirSync(colsDir)) {
|
|
118
|
+
if (file.endsWith(".json")) {
|
|
119
|
+
const id = path.basename(file, ".json");
|
|
120
|
+
collections[id] = await this.getCollection(id) || [];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
globals = await this.getGlobals() || {};
|
|
125
|
+
} catch {
|
|
126
|
+
}
|
|
127
|
+
return { pages, collections, globals };
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// src/content/local-cache-client.ts
|
|
134
|
+
var local_cache_client_exports = {};
|
|
135
|
+
__export(local_cache_client_exports, {
|
|
136
|
+
LocalCache: () => LocalCache2
|
|
137
|
+
});
|
|
138
|
+
var LocalCache2;
|
|
139
|
+
var init_local_cache_client = __esm({
|
|
140
|
+
"src/content/local-cache-client.ts"() {
|
|
141
|
+
"use strict";
|
|
142
|
+
LocalCache2 = class {
|
|
143
|
+
constructor(customPath) {
|
|
144
|
+
// Maintain private properties for type parity with the Server version
|
|
145
|
+
this.data = null;
|
|
146
|
+
this.hasLoaded = false;
|
|
147
|
+
this.cachePath = customPath || ".nexus/cache.json";
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Always returns false in the browser as local file caching
|
|
151
|
+
* is a server-side only feature.
|
|
152
|
+
*/
|
|
153
|
+
isLoaded() {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* No-op method to maintain internal API compatibility.
|
|
158
|
+
*/
|
|
159
|
+
load() {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Returns null. Browsers should fetch pages from the Remote API
|
|
164
|
+
* or the Memory/Browser cache.
|
|
165
|
+
*/
|
|
166
|
+
async getPage(_slug) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Returns null. Browsers should fetch collections from the Remote API.
|
|
171
|
+
*/
|
|
172
|
+
async getCollection(_collectionId) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Returns null.
|
|
177
|
+
*/
|
|
178
|
+
async getGlobals() {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Returns null.
|
|
183
|
+
*/
|
|
184
|
+
async getAllData() {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Dummy helper to match Node implementation.
|
|
189
|
+
*/
|
|
190
|
+
shouldWarnAboutMissingCache(error) {
|
|
191
|
+
const isMissing = error.code === "ENOENT";
|
|
192
|
+
const isMalformed = error instanceof SyntaxError;
|
|
193
|
+
if (process.env.NODE_ENV !== "development") return false;
|
|
194
|
+
return !isMissing || isMalformed;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
1
200
|
// src/config.ts
|
|
2
201
|
var DEFAULT_API_URL = "https://endpoints.gnexus.co.tz";
|
|
3
202
|
var DEFAULT_ANALYTICS_URL = "https://sentry.gnexus.co.tz";
|
|
@@ -313,10 +512,10 @@ var LocalCacheProxy = class {
|
|
|
313
512
|
async getInstance() {
|
|
314
513
|
if (this.instance) return this.instance;
|
|
315
514
|
if (typeof window === "undefined") {
|
|
316
|
-
const mod = await
|
|
515
|
+
const mod = await Promise.resolve().then(() => (init_local_cache_server(), local_cache_server_exports));
|
|
317
516
|
this.instance = new mod.LocalCache(this.cachePath);
|
|
318
517
|
} else {
|
|
319
|
-
const mod = await
|
|
518
|
+
const mod = await Promise.resolve().then(() => (init_local_cache_client(), local_cache_client_exports));
|
|
320
519
|
this.instance = new mod.LocalCache(this.cachePath);
|
|
321
520
|
}
|
|
322
521
|
return this.instance;
|
|
@@ -2257,342 +2456,10 @@ var NexusClient = class {
|
|
|
2257
2456
|
var nexus = new NexusClient();
|
|
2258
2457
|
var createNexusClient = (config) => new NexusClient(config);
|
|
2259
2458
|
|
|
2260
|
-
// src/components/NexusProvider.tsx
|
|
2261
|
-
import React2, {
|
|
2262
|
-
createContext as createContext2,
|
|
2263
|
-
useEffect as useEffect2,
|
|
2264
|
-
useRef,
|
|
2265
|
-
useMemo,
|
|
2266
|
-
useState as useState2,
|
|
2267
|
-
useCallback as useCallback2,
|
|
2268
|
-
Suspense
|
|
2269
|
-
} from "react";
|
|
2270
|
-
import { usePathname, useSearchParams } from "next/navigation";
|
|
2271
|
-
|
|
2272
|
-
// src/auth/context.tsx
|
|
2273
|
-
import {
|
|
2274
|
-
createContext,
|
|
2275
|
-
useContext,
|
|
2276
|
-
useEffect,
|
|
2277
|
-
useState,
|
|
2278
|
-
useCallback
|
|
2279
|
-
} from "react";
|
|
2280
|
-
import { jsx } from "react/jsx-runtime";
|
|
2281
|
-
var AuthContext = createContext(null);
|
|
2282
|
-
var AuthProvider = ({
|
|
2283
|
-
children,
|
|
2284
|
-
config
|
|
2285
|
-
}) => {
|
|
2286
|
-
const [user, setUser] = useState(null);
|
|
2287
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
2288
|
-
const [error, setError] = useState(null);
|
|
2289
|
-
const AUTH_BASE = `${config.apiUrl}/auth/project/${config.projectId}`;
|
|
2290
|
-
const checkSession = useCallback(async () => {
|
|
2291
|
-
try {
|
|
2292
|
-
const res = await fetch(`${AUTH_BASE}/me`, {
|
|
2293
|
-
headers: getHeaders(config)
|
|
2294
|
-
});
|
|
2295
|
-
if (res.ok) {
|
|
2296
|
-
const data = await res.json();
|
|
2297
|
-
setUser(data.user);
|
|
2298
|
-
if (nexus.analytics) {
|
|
2299
|
-
nexus.analytics.identify(data.user.id, {
|
|
2300
|
-
email: data.user.email,
|
|
2301
|
-
role: data.user.role,
|
|
2302
|
-
...data.user.metadata
|
|
2303
|
-
});
|
|
2304
|
-
}
|
|
2305
|
-
} else {
|
|
2306
|
-
setUser(null);
|
|
2307
|
-
}
|
|
2308
|
-
} catch (err) {
|
|
2309
|
-
console.debug("[NexusHub Auth] Session check failed:", err);
|
|
2310
|
-
setUser(null);
|
|
2311
|
-
} finally {
|
|
2312
|
-
setIsLoading(false);
|
|
2313
|
-
}
|
|
2314
|
-
}, [AUTH_BASE, config]);
|
|
2315
|
-
useEffect(() => {
|
|
2316
|
-
checkSession();
|
|
2317
|
-
}, [checkSession]);
|
|
2318
|
-
const login = async (creds) => {
|
|
2319
|
-
setIsLoading(true);
|
|
2320
|
-
setError(null);
|
|
2321
|
-
try {
|
|
2322
|
-
const res = await fetch(`${AUTH_BASE}/login`, {
|
|
2323
|
-
method: "POST",
|
|
2324
|
-
headers: getHeaders(config),
|
|
2325
|
-
body: JSON.stringify(creds)
|
|
2326
|
-
});
|
|
2327
|
-
if (!res.ok) throw await parseError(res);
|
|
2328
|
-
const data = await res.json();
|
|
2329
|
-
setUser(data.user);
|
|
2330
|
-
if (nexus.analytics) {
|
|
2331
|
-
await nexus.analytics.identify(data.user.id, {
|
|
2332
|
-
email: data.user.email,
|
|
2333
|
-
role: data.user.role,
|
|
2334
|
-
login_method: "email",
|
|
2335
|
-
...data.user.metadata
|
|
2336
|
-
});
|
|
2337
|
-
}
|
|
2338
|
-
} catch (err) {
|
|
2339
|
-
setError(err);
|
|
2340
|
-
throw err;
|
|
2341
|
-
} finally {
|
|
2342
|
-
setIsLoading(false);
|
|
2343
|
-
}
|
|
2344
|
-
};
|
|
2345
|
-
const register = async (creds) => {
|
|
2346
|
-
setIsLoading(true);
|
|
2347
|
-
setError(null);
|
|
2348
|
-
try {
|
|
2349
|
-
const res = await fetch(`${AUTH_BASE}/register`, {
|
|
2350
|
-
method: "POST",
|
|
2351
|
-
headers: getHeaders(config),
|
|
2352
|
-
body: JSON.stringify(creds)
|
|
2353
|
-
});
|
|
2354
|
-
if (!res.ok) throw await parseError(res);
|
|
2355
|
-
const data = await res.json();
|
|
2356
|
-
setUser(data.user);
|
|
2357
|
-
if (nexus.analytics) {
|
|
2358
|
-
nexus.analytics.track("signup", { method: "email" });
|
|
2359
|
-
nexus.analytics.identify(data.user.id, {
|
|
2360
|
-
email: data.user.email,
|
|
2361
|
-
role: data.user.role,
|
|
2362
|
-
...data.user.metadata
|
|
2363
|
-
});
|
|
2364
|
-
}
|
|
2365
|
-
} catch (err) {
|
|
2366
|
-
setError(err);
|
|
2367
|
-
throw err;
|
|
2368
|
-
} finally {
|
|
2369
|
-
setIsLoading(false);
|
|
2370
|
-
}
|
|
2371
|
-
};
|
|
2372
|
-
const logout = async () => {
|
|
2373
|
-
setIsLoading(true);
|
|
2374
|
-
try {
|
|
2375
|
-
await fetch(`${AUTH_BASE}/logout`, {
|
|
2376
|
-
method: "POST",
|
|
2377
|
-
headers: getHeaders(config)
|
|
2378
|
-
});
|
|
2379
|
-
} catch (e) {
|
|
2380
|
-
console.warn("Logout network error", e);
|
|
2381
|
-
} finally {
|
|
2382
|
-
setUser(null);
|
|
2383
|
-
setIsLoading(false);
|
|
2384
|
-
if (nexus.analytics) {
|
|
2385
|
-
nexus.analytics.track("logout");
|
|
2386
|
-
}
|
|
2387
|
-
}
|
|
2388
|
-
};
|
|
2389
|
-
const updateProfile = async (updates) => {
|
|
2390
|
-
try {
|
|
2391
|
-
const res = await fetch(`${AUTH_BASE}/profile`, {
|
|
2392
|
-
method: "PATCH",
|
|
2393
|
-
headers: getHeaders(config),
|
|
2394
|
-
body: JSON.stringify(updates)
|
|
2395
|
-
});
|
|
2396
|
-
if (!res.ok) throw await parseError(res);
|
|
2397
|
-
const data = await res.json();
|
|
2398
|
-
setUser(data.user);
|
|
2399
|
-
if (nexus.analytics) {
|
|
2400
|
-
nexus.analytics.identify(data.user.id, updates);
|
|
2401
|
-
}
|
|
2402
|
-
} catch (err) {
|
|
2403
|
-
setError(err);
|
|
2404
|
-
throw err;
|
|
2405
|
-
}
|
|
2406
|
-
};
|
|
2407
|
-
const requestPasswordReset = async (email) => {
|
|
2408
|
-
const res = await fetch(`${AUTH_BASE}/password/reset-request`, {
|
|
2409
|
-
method: "POST",
|
|
2410
|
-
headers: getHeaders(config),
|
|
2411
|
-
body: JSON.stringify({ email })
|
|
2412
|
-
});
|
|
2413
|
-
if (!res.ok) throw await parseError(res);
|
|
2414
|
-
};
|
|
2415
|
-
return /* @__PURE__ */ jsx(
|
|
2416
|
-
AuthContext.Provider,
|
|
2417
|
-
{
|
|
2418
|
-
value: {
|
|
2419
|
-
user,
|
|
2420
|
-
isLoading,
|
|
2421
|
-
error,
|
|
2422
|
-
isAuthenticated: !!user,
|
|
2423
|
-
login,
|
|
2424
|
-
register,
|
|
2425
|
-
logout,
|
|
2426
|
-
updateProfile,
|
|
2427
|
-
requestPasswordReset
|
|
2428
|
-
},
|
|
2429
|
-
children
|
|
2430
|
-
}
|
|
2431
|
-
);
|
|
2432
|
-
};
|
|
2433
|
-
var useNexusAuth = () => {
|
|
2434
|
-
const context = useContext(AuthContext);
|
|
2435
|
-
if (!context) {
|
|
2436
|
-
throw new Error("useNexusAuth must be used within a NexusProvider");
|
|
2437
|
-
}
|
|
2438
|
-
return context;
|
|
2439
|
-
};
|
|
2440
|
-
function getHeaders(config) {
|
|
2441
|
-
return {
|
|
2442
|
-
"Content-Type": "application/json",
|
|
2443
|
-
"x-nexus-project": config.projectId,
|
|
2444
|
-
Authorization: `Bearer ${config.apiKey}`
|
|
2445
|
-
// 👈 CRITICAL: Send the nx_pk_ key
|
|
2446
|
-
// Note: We do NOT send the Master API Key here.
|
|
2447
|
-
// This is client-side. The backend uses Cookies or public tokens.
|
|
2448
|
-
};
|
|
2449
|
-
}
|
|
2450
|
-
async function parseError(res) {
|
|
2451
|
-
try {
|
|
2452
|
-
const json = await res.json();
|
|
2453
|
-
return {
|
|
2454
|
-
status: res.status,
|
|
2455
|
-
code: json.code || "UNKNOWN_ERROR",
|
|
2456
|
-
message: json.message || "An error occurred during authentication"
|
|
2457
|
-
};
|
|
2458
|
-
} catch {
|
|
2459
|
-
return {
|
|
2460
|
-
status: res.status,
|
|
2461
|
-
code: "NETWORK_ERROR",
|
|
2462
|
-
message: res.statusText
|
|
2463
|
-
};
|
|
2464
|
-
}
|
|
2465
|
-
}
|
|
2466
|
-
|
|
2467
|
-
// src/components/NexusProvider.tsx
|
|
2468
|
-
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
2469
|
-
var NexusContext = createContext2(nexus);
|
|
2470
|
-
var NexusLiveFeedContext = createContext2({
|
|
2471
|
-
latestEvent: null,
|
|
2472
|
-
isConnected: false
|
|
2473
|
-
});
|
|
2474
|
-
function NexusAnalyticsTracker({
|
|
2475
|
-
disableAnalytics
|
|
2476
|
-
}) {
|
|
2477
|
-
const pathname = usePathname();
|
|
2478
|
-
const searchParams = useSearchParams();
|
|
2479
|
-
const prevPathRef = useRef("");
|
|
2480
|
-
const searchParamsString = searchParams.toString();
|
|
2481
|
-
useEffect2(() => {
|
|
2482
|
-
if (nexus.analytics && !disableAnalytics) {
|
|
2483
|
-
nexus.analytics.pageView(prevPathRef.current || document.referrer);
|
|
2484
|
-
prevPathRef.current = pathname;
|
|
2485
|
-
}
|
|
2486
|
-
}, [pathname, searchParamsString, disableAnalytics]);
|
|
2487
|
-
return /* @__PURE__ */ jsx2("div", { id: "__nexus_react_active", style: { display: "none" } });
|
|
2488
|
-
}
|
|
2489
|
-
var NexusProvider = ({
|
|
2490
|
-
children,
|
|
2491
|
-
projectId,
|
|
2492
|
-
disableAnalytics = false,
|
|
2493
|
-
hasConsent = true,
|
|
2494
|
-
// NEW: default true to preserve existing behaviour
|
|
2495
|
-
enableLiveFeed = false,
|
|
2496
|
-
// NEW
|
|
2497
|
-
onLiveEvent
|
|
2498
|
-
// NEW
|
|
2499
|
-
}) => {
|
|
2500
|
-
const isInitialized = useRef(false);
|
|
2501
|
-
const socketRef = useRef(null);
|
|
2502
|
-
const [latestEvent, setLatestEvent] = useState2(
|
|
2503
|
-
null
|
|
2504
|
-
);
|
|
2505
|
-
const [isConnected, setIsConnected] = useState2(false);
|
|
2506
|
-
const liveFeedValue = useMemo(
|
|
2507
|
-
() => ({ latestEvent, isConnected }),
|
|
2508
|
-
[latestEvent, isConnected]
|
|
2509
|
-
);
|
|
2510
|
-
const config = useMemo(() => {
|
|
2511
|
-
if (projectId && nexus.getConfig().projectId !== projectId) {
|
|
2512
|
-
nexus.updateConfig({ projectId });
|
|
2513
|
-
}
|
|
2514
|
-
return nexus.getConfig();
|
|
2515
|
-
}, [projectId]);
|
|
2516
|
-
useEffect2(() => {
|
|
2517
|
-
if (typeof window === "undefined" || disableAnalytics || !hasConsent)
|
|
2518
|
-
return;
|
|
2519
|
-
if (!isInitialized.current) {
|
|
2520
|
-
if (!nexus.analytics) {
|
|
2521
|
-
nexus.analytics = new AnalyticsEngine(nexus.getConfig());
|
|
2522
|
-
}
|
|
2523
|
-
nexus.analytics.start();
|
|
2524
|
-
isInitialized.current = true;
|
|
2525
|
-
if (nexus.getConfig().debug) {
|
|
2526
|
-
console.log("[NexusHub] \u{1F680} Provider initialized analytics");
|
|
2527
|
-
}
|
|
2528
|
-
}
|
|
2529
|
-
return () => {
|
|
2530
|
-
if (nexus.analytics) {
|
|
2531
|
-
nexus.analytics.stop();
|
|
2532
|
-
isInitialized.current = false;
|
|
2533
|
-
}
|
|
2534
|
-
};
|
|
2535
|
-
}, [disableAnalytics, hasConsent]);
|
|
2536
|
-
const connectLiveFeed = useCallback2(async () => {
|
|
2537
|
-
if (typeof window === "undefined" || !enableLiveFeed) return;
|
|
2538
|
-
try {
|
|
2539
|
-
const { io } = await import("socket.io-client");
|
|
2540
|
-
const cfg = nexus.getConfig();
|
|
2541
|
-
const wsUrl = cfg.apiUrl || "http://localhost:3001";
|
|
2542
|
-
const socket = io(`${wsUrl}/analytics`, {
|
|
2543
|
-
auth: { token: cfg.apiKey },
|
|
2544
|
-
query: { projectId: cfg.projectId },
|
|
2545
|
-
transports: ["websocket"],
|
|
2546
|
-
reconnectionAttempts: 5,
|
|
2547
|
-
reconnectionDelay: 2e3
|
|
2548
|
-
});
|
|
2549
|
-
socket.on("connect", () => {
|
|
2550
|
-
setIsConnected(true);
|
|
2551
|
-
if (cfg.debug) console.log("[NexusHub] \u{1F534} Live feed connected");
|
|
2552
|
-
});
|
|
2553
|
-
socket.on("disconnect", () => {
|
|
2554
|
-
setIsConnected(false);
|
|
2555
|
-
if (cfg.debug) console.log("[NexusHub] Live feed disconnected");
|
|
2556
|
-
});
|
|
2557
|
-
socket.on("live_event", (event) => {
|
|
2558
|
-
setLatestEvent(event);
|
|
2559
|
-
onLiveEvent?.(event);
|
|
2560
|
-
});
|
|
2561
|
-
socketRef.current = socket;
|
|
2562
|
-
} catch (err) {
|
|
2563
|
-
console.error("[NexusHub] Live feed connection failed:", err);
|
|
2564
|
-
}
|
|
2565
|
-
}, [enableLiveFeed, onLiveEvent]);
|
|
2566
|
-
useEffect2(() => {
|
|
2567
|
-
if (enableLiveFeed) {
|
|
2568
|
-
connectLiveFeed();
|
|
2569
|
-
}
|
|
2570
|
-
return () => {
|
|
2571
|
-
if (socketRef.current) {
|
|
2572
|
-
socketRef.current.disconnect();
|
|
2573
|
-
socketRef.current = null;
|
|
2574
|
-
setIsConnected(false);
|
|
2575
|
-
}
|
|
2576
|
-
};
|
|
2577
|
-
}, [enableLiveFeed, connectLiveFeed]);
|
|
2578
|
-
return /* @__PURE__ */ jsx2(NexusContext.Provider, { value: nexus, children: /* @__PURE__ */ jsx2(NexusLiveFeedContext.Provider, { value: liveFeedValue, children: /* @__PURE__ */ jsxs(AuthProvider, { config, children: [
|
|
2579
|
-
/* @__PURE__ */ jsx2(Suspense, { fallback: null, children: /* @__PURE__ */ jsx2(NexusAnalyticsTracker, { disableAnalytics }) }),
|
|
2580
|
-
children
|
|
2581
|
-
] }) }) });
|
|
2582
|
-
};
|
|
2583
|
-
var useNexus = () => {
|
|
2584
|
-
const context = React2.useContext(NexusContext);
|
|
2585
|
-
if (!context) {
|
|
2586
|
-
throw new Error("useNexus must be used within a NexusProvider");
|
|
2587
|
-
}
|
|
2588
|
-
return context;
|
|
2589
|
-
};
|
|
2590
|
-
|
|
2591
2459
|
// src/index.ts
|
|
2592
2460
|
var VERSION = "0.0.1";
|
|
2593
2461
|
export {
|
|
2594
2462
|
AnalyticsEngine,
|
|
2595
|
-
AuthProvider,
|
|
2596
2463
|
BrowserCache,
|
|
2597
2464
|
CacheTags,
|
|
2598
2465
|
ContentEngine,
|
|
@@ -2603,14 +2470,11 @@ export {
|
|
|
2603
2470
|
LocalCacheProxy as LocalCache,
|
|
2604
2471
|
MemoryCache,
|
|
2605
2472
|
NexusClient,
|
|
2606
|
-
NexusProvider,
|
|
2607
2473
|
VERSION,
|
|
2608
2474
|
createNexusClient,
|
|
2609
2475
|
getEnvConfig,
|
|
2610
2476
|
getFullConfig,
|
|
2611
2477
|
mergeConfigs,
|
|
2612
2478
|
nexus,
|
|
2613
|
-
useNexus,
|
|
2614
|
-
useNexusAuth,
|
|
2615
2479
|
validateConfig
|
|
2616
2480
|
};
|