@traffical/svelte 0.1.4 → 0.1.6
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/package.json +14 -17
- package/src/TrafficalProvider.svelte +0 -34
- package/src/context.svelte.ts +0 -232
- package/src/hooks.svelte.ts +0 -445
- package/src/index.test.ts +0 -221
- package/src/index.ts +0 -144
- package/src/server.ts +0 -68
- package/src/sveltekit.test.ts +0 -218
- package/src/sveltekit.ts +0 -139
- package/src/types.ts +0 -299
package/package.json
CHANGED
|
@@ -1,45 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@traffical/svelte",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Traffical SDK for Svelte 5 - Provider and hooks for parameter resolution with SSR support",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"svelte": "./
|
|
7
|
-
"main": "./
|
|
8
|
-
"module": "./
|
|
6
|
+
"svelte": "./dist/index.js",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
13
|
-
"svelte": "./
|
|
14
|
-
"
|
|
15
|
-
"import": "./src/index.ts"
|
|
13
|
+
"svelte": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
16
15
|
},
|
|
17
16
|
"./sveltekit": {
|
|
18
17
|
"types": "./dist/sveltekit.d.ts",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
18
|
+
"svelte": "./dist/sveltekit.js",
|
|
19
|
+
"default": "./dist/sveltekit.js"
|
|
21
20
|
},
|
|
22
21
|
"./server": {
|
|
23
22
|
"types": "./dist/server.d.ts",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
23
|
+
"svelte": "./dist/server.js",
|
|
24
|
+
"default": "./dist/server.js"
|
|
26
25
|
}
|
|
27
26
|
},
|
|
28
27
|
"files": [
|
|
29
|
-
"dist"
|
|
30
|
-
"src"
|
|
28
|
+
"dist"
|
|
31
29
|
],
|
|
32
30
|
"scripts": {
|
|
33
31
|
"build": "svelte-package --input src",
|
|
34
32
|
"dev": "svelte-package --input src --watch",
|
|
35
33
|
"test": "bun test",
|
|
36
|
-
"typecheck": "svelte-check --tsconfig ./tsconfig.json"
|
|
37
|
-
"release": "bun scripts/release.ts"
|
|
34
|
+
"typecheck": "svelte-check --tsconfig ./tsconfig.json"
|
|
38
35
|
},
|
|
39
36
|
"dependencies": {
|
|
40
|
-
"@traffical/core": "^0.1.
|
|
37
|
+
"@traffical/core": "^0.1.4",
|
|
41
38
|
"@traffical/js-client": "^0.1.4",
|
|
42
|
-
"@traffical/node": "^0.1.
|
|
39
|
+
"@traffical/node": "^0.1.5"
|
|
43
40
|
},
|
|
44
41
|
"devDependencies": {
|
|
45
42
|
"@sveltejs/package": "^2.3.0",
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
@traffical/svelte - TrafficalProvider Component
|
|
3
|
-
|
|
4
|
-
Wrapper component that initializes the Traffical context.
|
|
5
|
-
Alternative to calling initTraffical() directly in your layout.
|
|
6
|
-
-->
|
|
7
|
-
<script lang="ts">
|
|
8
|
-
import type { Snippet } from "svelte";
|
|
9
|
-
import { initTraffical } from "./context.svelte.js";
|
|
10
|
-
import type { TrafficalProviderConfig } from "./types.js";
|
|
11
|
-
|
|
12
|
-
interface Props {
|
|
13
|
-
/** Configuration for the Traffical client */
|
|
14
|
-
config: TrafficalProviderConfig;
|
|
15
|
-
/** Child content */
|
|
16
|
-
children: Snippet;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
let { config, children }: Props = $props();
|
|
20
|
-
|
|
21
|
-
// Initialize context - this sets up the client and makes it available to children
|
|
22
|
-
const context = initTraffical(config);
|
|
23
|
-
|
|
24
|
-
// Cleanup on component destroy
|
|
25
|
-
$effect(() => {
|
|
26
|
-
return () => {
|
|
27
|
-
// Destroy client when provider unmounts
|
|
28
|
-
context.client?.destroy();
|
|
29
|
-
};
|
|
30
|
-
});
|
|
31
|
-
</script>
|
|
32
|
-
|
|
33
|
-
{@render children()}
|
|
34
|
-
|
package/src/context.svelte.ts
DELETED
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @traffical/svelte - Context Layer
|
|
3
|
-
*
|
|
4
|
-
* SSR-safe context management using Svelte 5 runes and Svelte's context API.
|
|
5
|
-
* Initializes the TrafficalClient with environment-appropriate providers.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { getContext, setContext } from "svelte";
|
|
9
|
-
import {
|
|
10
|
-
TrafficalClient,
|
|
11
|
-
createTrafficalClientSync,
|
|
12
|
-
MemoryStorageProvider,
|
|
13
|
-
LocalStorageProvider,
|
|
14
|
-
} from "@traffical/js-client";
|
|
15
|
-
import type { Context as TrafficalContext } from "@traffical/core";
|
|
16
|
-
import type {
|
|
17
|
-
TrafficalProviderConfig,
|
|
18
|
-
TrafficalContextValue,
|
|
19
|
-
} from "./types.js";
|
|
20
|
-
|
|
21
|
-
// =============================================================================
|
|
22
|
-
// Constants
|
|
23
|
-
// =============================================================================
|
|
24
|
-
|
|
25
|
-
const TRAFFICAL_CONTEXT_KEY = Symbol("traffical");
|
|
26
|
-
|
|
27
|
-
// =============================================================================
|
|
28
|
-
// Browser Detection
|
|
29
|
-
// =============================================================================
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Check if we're running in a browser environment.
|
|
33
|
-
* SSR-safe - returns false during server-side rendering.
|
|
34
|
-
*/
|
|
35
|
-
function isBrowser(): boolean {
|
|
36
|
-
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// =============================================================================
|
|
40
|
-
// Context State Factory
|
|
41
|
-
// =============================================================================
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Creates the reactive Traffical context state.
|
|
45
|
-
* Uses $state for reactive properties that work with SSR.
|
|
46
|
-
*/
|
|
47
|
-
function createTrafficalContextState(
|
|
48
|
-
config: TrafficalProviderConfig
|
|
49
|
-
): TrafficalContextValue {
|
|
50
|
-
// Reactive state using Svelte 5 runes
|
|
51
|
-
let client = $state<TrafficalClient | null>(null);
|
|
52
|
-
let ready = $state(!!config.initialBundle); // Ready immediately if we have initial bundle
|
|
53
|
-
let error = $state<Error | null>(null);
|
|
54
|
-
let bundle = $state(config.initialBundle ?? null);
|
|
55
|
-
|
|
56
|
-
// Initialize client only in browser
|
|
57
|
-
if (isBrowser()) {
|
|
58
|
-
// Use localStorage in browser, memory storage would lose data
|
|
59
|
-
const storage = new LocalStorageProvider();
|
|
60
|
-
|
|
61
|
-
const clientInstance = createTrafficalClientSync({
|
|
62
|
-
orgId: config.orgId,
|
|
63
|
-
projectId: config.projectId,
|
|
64
|
-
env: config.env,
|
|
65
|
-
apiKey: config.apiKey,
|
|
66
|
-
baseUrl: config.baseUrl,
|
|
67
|
-
localConfig: config.initialBundle ?? config.localConfig,
|
|
68
|
-
refreshIntervalMs: config.refreshIntervalMs,
|
|
69
|
-
storage,
|
|
70
|
-
// Decision tracking options
|
|
71
|
-
trackDecisions: config.trackDecisions,
|
|
72
|
-
decisionDeduplicationTtlMs: config.decisionDeduplicationTtlMs,
|
|
73
|
-
// Exposure options
|
|
74
|
-
exposureSessionTtlMs: config.exposureSessionTtlMs,
|
|
75
|
-
// Event batching options
|
|
76
|
-
eventBatchSize: config.eventBatchSize,
|
|
77
|
-
eventFlushIntervalMs: config.eventFlushIntervalMs,
|
|
78
|
-
// Plugins
|
|
79
|
-
plugins: config.plugins,
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
client = clientInstance;
|
|
83
|
-
|
|
84
|
-
// Initialize asynchronously (fetches fresh config if needed)
|
|
85
|
-
clientInstance
|
|
86
|
-
.initialize()
|
|
87
|
-
.then(() => {
|
|
88
|
-
ready = true;
|
|
89
|
-
// Update bundle if client fetched a newer one
|
|
90
|
-
const configVersion = clientInstance.getConfigVersion();
|
|
91
|
-
if (configVersion) {
|
|
92
|
-
// Bundle is internal, but we track ready state
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
.catch((err: unknown) => {
|
|
96
|
-
error = err instanceof Error ? err : new Error(String(err));
|
|
97
|
-
// Still mark as ready - we'll use defaults/initial bundle
|
|
98
|
-
ready = true;
|
|
99
|
-
});
|
|
100
|
-
} else {
|
|
101
|
-
// On server, use memory storage and mark as ready if we have initial data
|
|
102
|
-
// The client won't actually be used for tracking on server
|
|
103
|
-
if (config.initialBundle) {
|
|
104
|
-
const storage = new MemoryStorageProvider();
|
|
105
|
-
const clientInstance = createTrafficalClientSync({
|
|
106
|
-
orgId: config.orgId,
|
|
107
|
-
projectId: config.projectId,
|
|
108
|
-
env: config.env,
|
|
109
|
-
apiKey: config.apiKey,
|
|
110
|
-
localConfig: config.initialBundle,
|
|
111
|
-
storage,
|
|
112
|
-
// Disable background operations on server
|
|
113
|
-
refreshIntervalMs: 0,
|
|
114
|
-
});
|
|
115
|
-
client = clientInstance;
|
|
116
|
-
ready = true;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Unit key getter - uses config function or client's stable ID
|
|
121
|
-
function getUnitKey(): string {
|
|
122
|
-
if (config.unitKeyFn) {
|
|
123
|
-
return config.unitKeyFn();
|
|
124
|
-
}
|
|
125
|
-
// Fall back to client's auto-generated stable ID
|
|
126
|
-
return client?.getStableId() ?? "";
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Context getter - merges unit key with additional context
|
|
130
|
-
function getContext(): TrafficalContext {
|
|
131
|
-
const unitKey = getUnitKey();
|
|
132
|
-
const additionalContext = config.contextFn?.() ?? {};
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
...additionalContext,
|
|
136
|
-
// Include common unit key field names for compatibility
|
|
137
|
-
userId: unitKey,
|
|
138
|
-
deviceId: unitKey,
|
|
139
|
-
anonymousId: unitKey,
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
get client() {
|
|
145
|
-
return client;
|
|
146
|
-
},
|
|
147
|
-
get ready() {
|
|
148
|
-
return ready;
|
|
149
|
-
},
|
|
150
|
-
get error() {
|
|
151
|
-
return error;
|
|
152
|
-
},
|
|
153
|
-
get bundle() {
|
|
154
|
-
return bundle;
|
|
155
|
-
},
|
|
156
|
-
getUnitKey,
|
|
157
|
-
getContext,
|
|
158
|
-
initialParams: config.initialParams,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// =============================================================================
|
|
163
|
-
// Public API
|
|
164
|
-
// =============================================================================
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Initializes the Traffical context.
|
|
168
|
-
* Must be called at the root of your application (e.g., in +layout.svelte).
|
|
169
|
-
*
|
|
170
|
-
* @example
|
|
171
|
-
* ```svelte
|
|
172
|
-
* <script>
|
|
173
|
-
* import { initTraffical } from '@traffical/svelte';
|
|
174
|
-
*
|
|
175
|
-
* let { data, children } = $props();
|
|
176
|
-
*
|
|
177
|
-
* initTraffical({
|
|
178
|
-
* orgId: 'org_123',
|
|
179
|
-
* projectId: 'proj_456',
|
|
180
|
-
* env: 'production',
|
|
181
|
-
* apiKey: 'pk_...',
|
|
182
|
-
* initialBundle: data.traffical?.bundle,
|
|
183
|
-
* });
|
|
184
|
-
* </script>
|
|
185
|
-
*
|
|
186
|
-
* {@render children()}
|
|
187
|
-
* ```
|
|
188
|
-
*/
|
|
189
|
-
export function initTraffical(
|
|
190
|
-
config: TrafficalProviderConfig
|
|
191
|
-
): TrafficalContextValue {
|
|
192
|
-
const contextValue = createTrafficalContextState(config);
|
|
193
|
-
setContext(TRAFFICAL_CONTEXT_KEY, contextValue);
|
|
194
|
-
return contextValue;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Gets the Traffical context value.
|
|
199
|
-
* Must be called within a component tree where initTraffical() has been called.
|
|
200
|
-
*
|
|
201
|
-
* @throws Error if called outside of Traffical context
|
|
202
|
-
*/
|
|
203
|
-
export function getTrafficalContext(): TrafficalContextValue {
|
|
204
|
-
const context = getContext<TrafficalContextValue | undefined>(
|
|
205
|
-
TRAFFICAL_CONTEXT_KEY
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
if (!context) {
|
|
209
|
-
throw new Error(
|
|
210
|
-
"getTrafficalContext() must be called within a component tree where initTraffical() has been called. " +
|
|
211
|
-
"Make sure to call initTraffical() in your root layout or wrap your app with <TrafficalProvider>."
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return context;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Checks if Traffical context is available.
|
|
220
|
-
* Useful for conditional rendering or optional Traffical integration.
|
|
221
|
-
*/
|
|
222
|
-
export function hasTrafficalContext(): boolean {
|
|
223
|
-
try {
|
|
224
|
-
const context = getContext<TrafficalContextValue | undefined>(
|
|
225
|
-
TRAFFICAL_CONTEXT_KEY
|
|
226
|
-
);
|
|
227
|
-
return context !== undefined;
|
|
228
|
-
} catch {
|
|
229
|
-
return false;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|