@jwiedeman/gtm-kit-svelte 1.0.1
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 +346 -0
- package/dist/index.cjs +18 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +165 -0
- package/dist/index.d.ts +165 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
# @react-gtm-kit/svelte
|
|
2
|
+
|
|
3
|
+
[](https://github.com/jwiedeman/react-gtm-kit/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/jwiedeman/react-gtm-kit)
|
|
5
|
+
[](https://www.npmjs.com/package/@react-gtm-kit/svelte)
|
|
6
|
+
[](https://bundlephobia.com/package/@react-gtm-kit/svelte)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://svelte.dev/)
|
|
10
|
+
|
|
11
|
+
**Svelte stores and context for Google Tag Manager. Reactive by design.**
|
|
12
|
+
|
|
13
|
+
The Svelte adapter for GTM Kit - provides stores and context for idiomatic Svelte integration.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @react-gtm-kit/core @react-gtm-kit/svelte
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
yarn add @react-gtm-kit/core @react-gtm-kit/svelte
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add @react-gtm-kit/core @react-gtm-kit/svelte
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### Step 1: Create Store in Layout
|
|
36
|
+
|
|
37
|
+
```svelte
|
|
38
|
+
<!-- src/routes/+layout.svelte -->
|
|
39
|
+
<script>
|
|
40
|
+
import { createGtmStore, setGtmContext } from '@react-gtm-kit/svelte';
|
|
41
|
+
|
|
42
|
+
const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });
|
|
43
|
+
setGtmContext(gtm);
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<slot />
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Step 2: Push Events
|
|
50
|
+
|
|
51
|
+
```svelte
|
|
52
|
+
<!-- src/routes/+page.svelte -->
|
|
53
|
+
<script>
|
|
54
|
+
import { getGtmContext } from '@react-gtm-kit/svelte';
|
|
55
|
+
|
|
56
|
+
const gtm = getGtmContext();
|
|
57
|
+
|
|
58
|
+
function handleClick() {
|
|
59
|
+
$gtm.push({ event: 'purchase', value: 49.99 });
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<button on:click={handleClick}>Buy Now</button>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**That's it!** GTM is now running.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Features
|
|
71
|
+
|
|
72
|
+
| Feature | Description |
|
|
73
|
+
|---------|-------------|
|
|
74
|
+
| **Svelte Stores** | Native Svelte store integration |
|
|
75
|
+
| **Context API** | Uses Svelte context for DI |
|
|
76
|
+
| **Reactive** | Fully reactive with `$` syntax |
|
|
77
|
+
| **TypeScript** | Full type definitions included |
|
|
78
|
+
| **Consent Mode v2** | Built-in GDPR compliance |
|
|
79
|
+
| **SSR Compatible** | Safe for SvelteKit SSR |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Available Functions
|
|
84
|
+
|
|
85
|
+
### `createGtmStore(options)`
|
|
86
|
+
|
|
87
|
+
Creates a new GTM store. Call this once in your root layout.
|
|
88
|
+
|
|
89
|
+
```svelte
|
|
90
|
+
<script>
|
|
91
|
+
import { createGtmStore, setGtmContext } from '@react-gtm-kit/svelte';
|
|
92
|
+
|
|
93
|
+
const gtm = createGtmStore({
|
|
94
|
+
containers: 'GTM-XXXXXX',
|
|
95
|
+
autoInit: true, // default
|
|
96
|
+
onBeforeInit: (client) => {
|
|
97
|
+
// Set consent defaults here
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
setGtmContext(gtm);
|
|
102
|
+
</script>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `getGtmContext()`
|
|
106
|
+
|
|
107
|
+
Gets the GTM store from context. Use in child components.
|
|
108
|
+
|
|
109
|
+
```svelte
|
|
110
|
+
<script>
|
|
111
|
+
import { getGtmContext } from '@react-gtm-kit/svelte';
|
|
112
|
+
|
|
113
|
+
const gtm = getGtmContext();
|
|
114
|
+
|
|
115
|
+
// Access store values reactively
|
|
116
|
+
$: ({ push, client, updateConsent } = $gtm);
|
|
117
|
+
</script>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### `gtmPush()`
|
|
121
|
+
|
|
122
|
+
Get a derived store for just the push function.
|
|
123
|
+
|
|
124
|
+
```svelte
|
|
125
|
+
<script>
|
|
126
|
+
import { gtmPush } from '@react-gtm-kit/svelte';
|
|
127
|
+
|
|
128
|
+
const push = gtmPush();
|
|
129
|
+
|
|
130
|
+
function track() {
|
|
131
|
+
$push({ event: 'button_click' });
|
|
132
|
+
}
|
|
133
|
+
</script>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### `gtmConsent()`
|
|
137
|
+
|
|
138
|
+
Get a derived store for consent functions.
|
|
139
|
+
|
|
140
|
+
```svelte
|
|
141
|
+
<script>
|
|
142
|
+
import { gtmConsent } from '@react-gtm-kit/svelte';
|
|
143
|
+
|
|
144
|
+
const consent = gtmConsent();
|
|
145
|
+
|
|
146
|
+
function acceptAll() {
|
|
147
|
+
$consent.updateConsent({
|
|
148
|
+
ad_storage: 'granted',
|
|
149
|
+
analytics_storage: 'granted'
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
</script>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### `gtmClient()`
|
|
156
|
+
|
|
157
|
+
Get a derived store for the raw GTM client.
|
|
158
|
+
|
|
159
|
+
```svelte
|
|
160
|
+
<script>
|
|
161
|
+
import { gtmClient } from '@react-gtm-kit/svelte';
|
|
162
|
+
|
|
163
|
+
const client = gtmClient();
|
|
164
|
+
</script>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### `gtmReady()`
|
|
168
|
+
|
|
169
|
+
Get a derived store for the whenReady function.
|
|
170
|
+
|
|
171
|
+
```svelte
|
|
172
|
+
<script>
|
|
173
|
+
import { gtmReady } from '@react-gtm-kit/svelte';
|
|
174
|
+
import { onMount } from 'svelte';
|
|
175
|
+
|
|
176
|
+
const whenReady = gtmReady();
|
|
177
|
+
|
|
178
|
+
onMount(async () => {
|
|
179
|
+
await $whenReady();
|
|
180
|
+
console.log('GTM is ready!');
|
|
181
|
+
});
|
|
182
|
+
</script>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## SvelteKit Integration
|
|
188
|
+
|
|
189
|
+
### Basic Setup
|
|
190
|
+
|
|
191
|
+
```svelte
|
|
192
|
+
<!-- src/routes/+layout.svelte -->
|
|
193
|
+
<script>
|
|
194
|
+
import { createGtmStore, setGtmContext } from '@react-gtm-kit/svelte';
|
|
195
|
+
import { browser } from '$app/environment';
|
|
196
|
+
|
|
197
|
+
// Only create store in browser
|
|
198
|
+
if (browser) {
|
|
199
|
+
const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });
|
|
200
|
+
setGtmContext(gtm);
|
|
201
|
+
}
|
|
202
|
+
</script>
|
|
203
|
+
|
|
204
|
+
<slot />
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Page Tracking
|
|
208
|
+
|
|
209
|
+
```svelte
|
|
210
|
+
<!-- src/routes/+layout.svelte -->
|
|
211
|
+
<script>
|
|
212
|
+
import { createGtmStore, setGtmContext } from '@react-gtm-kit/svelte';
|
|
213
|
+
import { page } from '$app/stores';
|
|
214
|
+
import { browser } from '$app/environment';
|
|
215
|
+
|
|
216
|
+
let gtm;
|
|
217
|
+
|
|
218
|
+
if (browser) {
|
|
219
|
+
gtm = createGtmStore({ containers: 'GTM-XXXXXX' });
|
|
220
|
+
setGtmContext(gtm);
|
|
221
|
+
|
|
222
|
+
// Track page views
|
|
223
|
+
$: if ($gtm && $page) {
|
|
224
|
+
$gtm.push({
|
|
225
|
+
event: 'page_view',
|
|
226
|
+
page_path: $page.url.pathname
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
</script>
|
|
231
|
+
|
|
232
|
+
<slot />
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Consent Mode v2 (GDPR)
|
|
238
|
+
|
|
239
|
+
```svelte
|
|
240
|
+
<!-- src/routes/+layout.svelte -->
|
|
241
|
+
<script>
|
|
242
|
+
import { createGtmStore, setGtmContext } from '@react-gtm-kit/svelte';
|
|
243
|
+
import { consentPresets } from '@react-gtm-kit/core';
|
|
244
|
+
import { browser } from '$app/environment';
|
|
245
|
+
|
|
246
|
+
if (browser) {
|
|
247
|
+
const gtm = createGtmStore({
|
|
248
|
+
containers: 'GTM-XXXXXX',
|
|
249
|
+
onBeforeInit: (client) => {
|
|
250
|
+
// Deny by default for EU users
|
|
251
|
+
client.setConsentDefaults(consentPresets.eeaDefault, { region: ['EEA'] });
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
setGtmContext(gtm);
|
|
255
|
+
}
|
|
256
|
+
</script>
|
|
257
|
+
|
|
258
|
+
<slot />
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
```svelte
|
|
262
|
+
<!-- src/lib/CookieBanner.svelte -->
|
|
263
|
+
<script>
|
|
264
|
+
import { gtmConsent } from '@react-gtm-kit/svelte';
|
|
265
|
+
|
|
266
|
+
const consent = gtmConsent();
|
|
267
|
+
|
|
268
|
+
function acceptAll() {
|
|
269
|
+
$consent.updateConsent({
|
|
270
|
+
ad_storage: 'granted',
|
|
271
|
+
analytics_storage: 'granted',
|
|
272
|
+
ad_user_data: 'granted',
|
|
273
|
+
ad_personalization: 'granted'
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function rejectAll() {
|
|
278
|
+
$consent.updateConsent({
|
|
279
|
+
ad_storage: 'denied',
|
|
280
|
+
analytics_storage: 'denied',
|
|
281
|
+
ad_user_data: 'denied',
|
|
282
|
+
ad_personalization: 'denied'
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
</script>
|
|
286
|
+
|
|
287
|
+
<div class="cookie-banner">
|
|
288
|
+
<p>We use cookies to improve your experience.</p>
|
|
289
|
+
<button on:click={acceptAll}>Accept All</button>
|
|
290
|
+
<button on:click={rejectAll}>Reject All</button>
|
|
291
|
+
</div>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Store Options
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
interface GtmStoreOptions {
|
|
300
|
+
// Required: GTM container ID(s)
|
|
301
|
+
containers: string | ContainerConfig | (string | ContainerConfig)[];
|
|
302
|
+
|
|
303
|
+
// Whether to auto-initialize GTM (default: true)
|
|
304
|
+
autoInit?: boolean;
|
|
305
|
+
|
|
306
|
+
// Custom dataLayer name (default: 'dataLayer')
|
|
307
|
+
dataLayerName?: string;
|
|
308
|
+
|
|
309
|
+
// Custom GTM host
|
|
310
|
+
host?: string;
|
|
311
|
+
|
|
312
|
+
// Script attributes (e.g., nonce for CSP)
|
|
313
|
+
scriptAttributes?: Record<string, string>;
|
|
314
|
+
|
|
315
|
+
// Called before GTM initializes
|
|
316
|
+
onBeforeInit?: (client: GtmClient) => void;
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## TypeScript
|
|
323
|
+
|
|
324
|
+
Full TypeScript support is included:
|
|
325
|
+
|
|
326
|
+
```svelte
|
|
327
|
+
<script lang="ts">
|
|
328
|
+
import { getGtmContext, type GtmStoreValue } from '@react-gtm-kit/svelte';
|
|
329
|
+
import type { Writable } from 'svelte/store';
|
|
330
|
+
|
|
331
|
+
const gtm: Writable<GtmStoreValue> = getGtmContext();
|
|
332
|
+
</script>
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Requirements
|
|
338
|
+
|
|
339
|
+
- Svelte 4.0+ or 5.0+
|
|
340
|
+
- `@react-gtm-kit/core` (peer dependency)
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## License
|
|
345
|
+
|
|
346
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var store = require('svelte/store');
|
|
4
|
+
var svelte = require('svelte');
|
|
5
|
+
var gtmKit = require('@jwiedeman/gtm-kit');
|
|
6
|
+
|
|
7
|
+
var l=Symbol("gtm-kit");function G(t){let{autoInit:e=!0,onBeforeInit:r,...m}=t,o=gtmKit.createGtmClient(m),p=store.writable({client:o,push:n=>o.push(n),setConsentDefaults:(n,s)=>o.setConsentDefaults(n,s),updateConsent:(n,s)=>o.updateConsent(n,s),whenReady:()=>o.whenReady(),onReady:n=>o.onReady(n),initialized:!1});return r&&r(o),e&&(o.init(),p.update(n=>({...n,initialized:!0}))),p}function a(){let t=svelte.getContext(l);if(!t)throw new Error("[gtm-kit] getGtmContext() was called outside of a component tree with GTM context. Make sure to call setGtmContext() in a parent component.");return t}function S(t){svelte.setContext(l,t);}var f=a;function x(){let t=a();return store.derived(t,e=>e.push)}function g(){let t=a();return store.derived(t,e=>({setConsentDefaults:e.setConsentDefaults,updateConsent:e.updateConsent}))}function y(){let t=a();return store.derived(t,e=>e.client)}function R(){let t=a();return store.derived(t,e=>e.whenReady)}
|
|
8
|
+
|
|
9
|
+
exports.createGtmStore = G;
|
|
10
|
+
exports.getGtmContext = a;
|
|
11
|
+
exports.gtmClient = y;
|
|
12
|
+
exports.gtmConsent = g;
|
|
13
|
+
exports.gtmContext = f;
|
|
14
|
+
exports.gtmPush = x;
|
|
15
|
+
exports.gtmReady = R;
|
|
16
|
+
exports.setGtmContext = S;
|
|
17
|
+
//# sourceMappingURL=out.js.map
|
|
18
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/store.ts"],"names":["writable","derived","getContext","setContext","createGtmClient","GTM_CONTEXT_KEY","createGtmStore","options","autoInit","onBeforeInit","clientOptions","client","store","value","state","regionOptions","callback","s","getGtmContext","context","setGtmContext","gtmContext","gtmPush","$store","gtmConsent","gtmClient","gtmReady"],"mappings":"AAAA,OAAS,YAAAA,EAAU,WAAAC,MAA6C,eAChE,OAAS,cAAAC,EAAY,cAAAC,MAAkB,SACvC,OACE,mBAAAC,MAOK,qBAiDP,IAAMC,EAAkB,OAAO,SAAS,EAgBjC,SAASC,EAAeC,EAAmD,CAChF,GAAM,CAAE,SAAAC,EAAW,GAAM,aAAAC,EAAc,GAAGC,CAAc,EAAIH,EAEtDI,EAASP,EAAgBM,CAAa,EActCE,EAAQZ,EAZsB,CAClC,OAAAW,EACA,KAAOE,GAA0BF,EAAO,KAAKE,CAAK,EAClD,mBAAoB,CAACC,EAAqBC,IACxCJ,EAAO,mBAAmBG,EAAOC,CAAa,EAChD,cAAe,CAACD,EAAqBC,IACnCJ,EAAO,cAAcG,EAAOC,CAAa,EAC3C,UAAW,IAAMJ,EAAO,UAAU,EAClC,QAAUK,GAAiDL,EAAO,QAAQK,CAAQ,EAClF,YAAa,EACf,CAEkD,EAGlD,OAAIP,GACFA,EAAaE,CAAM,EAIjBH,IACFG,EAAO,KAAK,EACZC,EAAM,OAAQK,IAAO,CAAE,GAAGA,EAAG,YAAa,EAAK,EAAE,GAG5CL,CACT,CAgBO,SAASM,GAAyC,CACvD,IAAMC,EAAUjB,EAAoCG,CAAe,EACnE,GAAI,CAACc,EACH,MAAM,IAAI,MACR,6IAEF,EAEF,OAAOA,CACT,CAkBO,SAASC,EAAcR,EAAsC,CAClET,EAAWE,EAAiBO,CAAK,CACnC,CAKO,IAAMS,EAAaH,EAmBnB,SAASI,GAAqD,CACnE,IAAMV,EAAQM,EAAc,EAC5B,OAAOjB,EAAQW,EAAQW,GAAWA,EAAO,IAAI,CAC/C,CAkBO,SAASC,GAAsC,CACpD,IAAMZ,EAAQM,EAAc,EAC5B,OAAOjB,EAAQW,EAAQW,IAAY,CACjC,mBAAoBA,EAAO,mBAC3B,cAAeA,EAAO,aACxB,EAAE,CACJ,CAcO,SAASE,GAAiC,CAC/C,IAAMb,EAAQM,EAAc,EAC5B,OAAOjB,EAAQW,EAAQW,GAAWA,EAAO,MAAM,CACjD,CAoBO,SAASG,GAAuD,CACrE,IAAMd,EAAQM,EAAc,EAC5B,OAAOjB,EAAQW,EAAQW,GAAWA,EAAO,SAAS,CACpD","sourcesContent":["import { writable, derived, type Writable, type Readable } from 'svelte/store';\nimport { getContext, setContext } from 'svelte';\nimport {\n createGtmClient,\n type ConsentRegionOptions,\n type ConsentState,\n type CreateGtmClientOptions,\n type DataLayerValue,\n type GtmClient,\n type ScriptLoadState\n} from '@jwiedeman/gtm-kit';\n\n/**\n * Options for creating a GTM store.\n * Extends CreateGtmClientOptions with Svelte-specific options.\n */\nexport interface GtmStoreOptions extends CreateGtmClientOptions {\n /**\n * Whether to automatically initialize GTM when the store is created.\n * @default true\n */\n autoInit?: boolean;\n\n /**\n * Callback executed before GTM initialization.\n * Use this to set consent defaults.\n */\n onBeforeInit?: (client: GtmClient) => void;\n}\n\n/**\n * The GTM store value containing all GTM functionality.\n */\nexport interface GtmStoreValue {\n /** The underlying GTM client instance */\n client: GtmClient;\n /** Push a value to the data layer */\n push: (value: DataLayerValue) => void;\n /** Set consent defaults (must be called before init) */\n setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;\n /** Update consent state */\n updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;\n /** Returns a promise that resolves when all GTM scripts are loaded */\n whenReady: () => Promise<ScriptLoadState[]>;\n /** Register a callback for when GTM scripts are ready */\n onReady: (callback: (state: ScriptLoadState[]) => void) => () => void;\n /** Whether GTM has been initialized */\n initialized: boolean;\n}\n\n/**\n * Consent-specific API subset.\n */\nexport interface GtmConsentApi {\n setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;\n updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;\n}\n\n/** Context key for GTM store */\nconst GTM_CONTEXT_KEY = Symbol('gtm-kit');\n\n/**\n * Create a GTM store for Svelte.\n *\n * @example\n * ```svelte\n * <script>\n * import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';\n * import { onMount } from 'svelte';\n *\n * const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });\n * setGtmContext(gtm);\n * </script>\n * ```\n */\nexport function createGtmStore(options: GtmStoreOptions): Writable<GtmStoreValue> {\n const { autoInit = true, onBeforeInit, ...clientOptions } = options;\n\n const client = createGtmClient(clientOptions);\n\n const initialValue: GtmStoreValue = {\n client,\n push: (value: DataLayerValue) => client.push(value),\n setConsentDefaults: (state: ConsentState, regionOptions?: ConsentRegionOptions) =>\n client.setConsentDefaults(state, regionOptions),\n updateConsent: (state: ConsentState, regionOptions?: ConsentRegionOptions) =>\n client.updateConsent(state, regionOptions),\n whenReady: () => client.whenReady(),\n onReady: (callback: (state: ScriptLoadState[]) => void) => client.onReady(callback),\n initialized: false\n };\n\n const store = writable<GtmStoreValue>(initialValue);\n\n // Call onBeforeInit hook if provided (for consent defaults)\n if (onBeforeInit) {\n onBeforeInit(client);\n }\n\n // Auto-initialize if enabled\n if (autoInit) {\n client.init();\n store.update((s) => ({ ...s, initialized: true }));\n }\n\n return store;\n}\n\n/**\n * Get the GTM context from a parent component.\n * Must be called during component initialization.\n *\n * @example\n * ```svelte\n * <script>\n * import { getGtmContext } from '@jwiedeman/gtm-kit-svelte';\n *\n * const gtm = getGtmContext();\n * $: ({ push } = $gtm);\n * </script>\n * ```\n */\nexport function getGtmContext(): Writable<GtmStoreValue> {\n const context = getContext<Writable<GtmStoreValue>>(GTM_CONTEXT_KEY);\n if (!context) {\n throw new Error(\n '[gtm-kit] getGtmContext() was called outside of a component tree with GTM context. ' +\n 'Make sure to call setGtmContext() in a parent component.'\n );\n }\n return context;\n}\n\n/**\n * Set the GTM context for child components.\n * Call this in your root layout or App component.\n *\n * @example\n * ```svelte\n * <script>\n * import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';\n *\n * const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });\n * setGtmContext(gtm);\n * </script>\n *\n * <slot />\n * ```\n */\nexport function setGtmContext(store: Writable<GtmStoreValue>): void {\n setContext(GTM_CONTEXT_KEY, store);\n}\n\n/**\n * Alias for getGtmContext() - get the full GTM store.\n */\nexport const gtmContext = getGtmContext;\n\n/**\n * Get a derived store that provides just the push function.\n * Use this when you only need to push events.\n *\n * @example\n * ```svelte\n * <script>\n * import { gtmPush } from '@jwiedeman/gtm-kit-svelte';\n *\n * const push = gtmPush();\n *\n * function handleClick() {\n * $push({ event: 'button_click' });\n * }\n * </script>\n * ```\n */\nexport function gtmPush(): Readable<(value: DataLayerValue) => void> {\n const store = getGtmContext();\n return derived(store, ($store) => $store.push);\n}\n\n/**\n * Get a derived store that provides consent functions.\n *\n * @example\n * ```svelte\n * <script>\n * import { gtmConsent } from '@jwiedeman/gtm-kit-svelte';\n *\n * const consent = gtmConsent();\n *\n * function acceptAll() {\n * $consent.updateConsent({ analytics_storage: 'granted' });\n * }\n * </script>\n * ```\n */\nexport function gtmConsent(): Readable<GtmConsentApi> {\n const store = getGtmContext();\n return derived(store, ($store) => ({\n setConsentDefaults: $store.setConsentDefaults,\n updateConsent: $store.updateConsent\n }));\n}\n\n/**\n * Get a derived store that provides the raw GTM client.\n *\n * @example\n * ```svelte\n * <script>\n * import { gtmClient } from '@jwiedeman/gtm-kit-svelte';\n *\n * const client = gtmClient();\n * </script>\n * ```\n */\nexport function gtmClient(): Readable<GtmClient> {\n const store = getGtmContext();\n return derived(store, ($store) => $store.client);\n}\n\n/**\n * Get a derived store that provides the whenReady function.\n *\n * @example\n * ```svelte\n * <script>\n * import { gtmReady } from '@jwiedeman/gtm-kit-svelte';\n * import { onMount } from 'svelte';\n *\n * const whenReady = gtmReady();\n *\n * onMount(async () => {\n * const states = await $whenReady();\n * console.log('GTM loaded:', states);\n * });\n * </script>\n * ```\n */\nexport function gtmReady(): Readable<() => Promise<ScriptLoadState[]>> {\n const store = getGtmContext();\n return derived(store, ($store) => $store.whenReady);\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { Writable, Readable } from 'svelte/store';
|
|
2
|
+
import { CreateGtmClientOptions, GtmClient, DataLayerValue, ConsentState, ConsentRegionOptions, ScriptLoadState } from '@jwiedeman/gtm-kit';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Options for creating a GTM store.
|
|
6
|
+
* Extends CreateGtmClientOptions with Svelte-specific options.
|
|
7
|
+
*/
|
|
8
|
+
interface GtmStoreOptions extends CreateGtmClientOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Whether to automatically initialize GTM when the store is created.
|
|
11
|
+
* @default true
|
|
12
|
+
*/
|
|
13
|
+
autoInit?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Callback executed before GTM initialization.
|
|
16
|
+
* Use this to set consent defaults.
|
|
17
|
+
*/
|
|
18
|
+
onBeforeInit?: (client: GtmClient) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The GTM store value containing all GTM functionality.
|
|
22
|
+
*/
|
|
23
|
+
interface GtmStoreValue {
|
|
24
|
+
/** The underlying GTM client instance */
|
|
25
|
+
client: GtmClient;
|
|
26
|
+
/** Push a value to the data layer */
|
|
27
|
+
push: (value: DataLayerValue) => void;
|
|
28
|
+
/** Set consent defaults (must be called before init) */
|
|
29
|
+
setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
30
|
+
/** Update consent state */
|
|
31
|
+
updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
32
|
+
/** Returns a promise that resolves when all GTM scripts are loaded */
|
|
33
|
+
whenReady: () => Promise<ScriptLoadState[]>;
|
|
34
|
+
/** Register a callback for when GTM scripts are ready */
|
|
35
|
+
onReady: (callback: (state: ScriptLoadState[]) => void) => () => void;
|
|
36
|
+
/** Whether GTM has been initialized */
|
|
37
|
+
initialized: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Consent-specific API subset.
|
|
41
|
+
*/
|
|
42
|
+
interface GtmConsentApi {
|
|
43
|
+
setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
44
|
+
updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create a GTM store for Svelte.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```svelte
|
|
51
|
+
* <script>
|
|
52
|
+
* import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';
|
|
53
|
+
* import { onMount } from 'svelte';
|
|
54
|
+
*
|
|
55
|
+
* const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });
|
|
56
|
+
* setGtmContext(gtm);
|
|
57
|
+
* </script>
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
declare function createGtmStore(options: GtmStoreOptions): Writable<GtmStoreValue>;
|
|
61
|
+
/**
|
|
62
|
+
* Get the GTM context from a parent component.
|
|
63
|
+
* Must be called during component initialization.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```svelte
|
|
67
|
+
* <script>
|
|
68
|
+
* import { getGtmContext } from '@jwiedeman/gtm-kit-svelte';
|
|
69
|
+
*
|
|
70
|
+
* const gtm = getGtmContext();
|
|
71
|
+
* $: ({ push } = $gtm);
|
|
72
|
+
* </script>
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
declare function getGtmContext(): Writable<GtmStoreValue>;
|
|
76
|
+
/**
|
|
77
|
+
* Set the GTM context for child components.
|
|
78
|
+
* Call this in your root layout or App component.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```svelte
|
|
82
|
+
* <script>
|
|
83
|
+
* import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';
|
|
84
|
+
*
|
|
85
|
+
* const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });
|
|
86
|
+
* setGtmContext(gtm);
|
|
87
|
+
* </script>
|
|
88
|
+
*
|
|
89
|
+
* <slot />
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
declare function setGtmContext(store: Writable<GtmStoreValue>): void;
|
|
93
|
+
/**
|
|
94
|
+
* Alias for getGtmContext() - get the full GTM store.
|
|
95
|
+
*/
|
|
96
|
+
declare const gtmContext: typeof getGtmContext;
|
|
97
|
+
/**
|
|
98
|
+
* Get a derived store that provides just the push function.
|
|
99
|
+
* Use this when you only need to push events.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```svelte
|
|
103
|
+
* <script>
|
|
104
|
+
* import { gtmPush } from '@jwiedeman/gtm-kit-svelte';
|
|
105
|
+
*
|
|
106
|
+
* const push = gtmPush();
|
|
107
|
+
*
|
|
108
|
+
* function handleClick() {
|
|
109
|
+
* $push({ event: 'button_click' });
|
|
110
|
+
* }
|
|
111
|
+
* </script>
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function gtmPush(): Readable<(value: DataLayerValue) => void>;
|
|
115
|
+
/**
|
|
116
|
+
* Get a derived store that provides consent functions.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```svelte
|
|
120
|
+
* <script>
|
|
121
|
+
* import { gtmConsent } from '@jwiedeman/gtm-kit-svelte';
|
|
122
|
+
*
|
|
123
|
+
* const consent = gtmConsent();
|
|
124
|
+
*
|
|
125
|
+
* function acceptAll() {
|
|
126
|
+
* $consent.updateConsent({ analytics_storage: 'granted' });
|
|
127
|
+
* }
|
|
128
|
+
* </script>
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
declare function gtmConsent(): Readable<GtmConsentApi>;
|
|
132
|
+
/**
|
|
133
|
+
* Get a derived store that provides the raw GTM client.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```svelte
|
|
137
|
+
* <script>
|
|
138
|
+
* import { gtmClient } from '@jwiedeman/gtm-kit-svelte';
|
|
139
|
+
*
|
|
140
|
+
* const client = gtmClient();
|
|
141
|
+
* </script>
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
declare function gtmClient(): Readable<GtmClient>;
|
|
145
|
+
/**
|
|
146
|
+
* Get a derived store that provides the whenReady function.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```svelte
|
|
150
|
+
* <script>
|
|
151
|
+
* import { gtmReady } from '@jwiedeman/gtm-kit-svelte';
|
|
152
|
+
* import { onMount } from 'svelte';
|
|
153
|
+
*
|
|
154
|
+
* const whenReady = gtmReady();
|
|
155
|
+
*
|
|
156
|
+
* onMount(async () => {
|
|
157
|
+
* const states = await $whenReady();
|
|
158
|
+
* console.log('GTM loaded:', states);
|
|
159
|
+
* });
|
|
160
|
+
* </script>
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
declare function gtmReady(): Readable<() => Promise<ScriptLoadState[]>>;
|
|
164
|
+
|
|
165
|
+
export { GtmConsentApi, GtmStoreOptions, GtmStoreValue, createGtmStore, getGtmContext, gtmClient, gtmConsent, gtmContext, gtmPush, gtmReady, setGtmContext };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { Writable, Readable } from 'svelte/store';
|
|
2
|
+
import { CreateGtmClientOptions, GtmClient, DataLayerValue, ConsentState, ConsentRegionOptions, ScriptLoadState } from '@jwiedeman/gtm-kit';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Options for creating a GTM store.
|
|
6
|
+
* Extends CreateGtmClientOptions with Svelte-specific options.
|
|
7
|
+
*/
|
|
8
|
+
interface GtmStoreOptions extends CreateGtmClientOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Whether to automatically initialize GTM when the store is created.
|
|
11
|
+
* @default true
|
|
12
|
+
*/
|
|
13
|
+
autoInit?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Callback executed before GTM initialization.
|
|
16
|
+
* Use this to set consent defaults.
|
|
17
|
+
*/
|
|
18
|
+
onBeforeInit?: (client: GtmClient) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The GTM store value containing all GTM functionality.
|
|
22
|
+
*/
|
|
23
|
+
interface GtmStoreValue {
|
|
24
|
+
/** The underlying GTM client instance */
|
|
25
|
+
client: GtmClient;
|
|
26
|
+
/** Push a value to the data layer */
|
|
27
|
+
push: (value: DataLayerValue) => void;
|
|
28
|
+
/** Set consent defaults (must be called before init) */
|
|
29
|
+
setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
30
|
+
/** Update consent state */
|
|
31
|
+
updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
32
|
+
/** Returns a promise that resolves when all GTM scripts are loaded */
|
|
33
|
+
whenReady: () => Promise<ScriptLoadState[]>;
|
|
34
|
+
/** Register a callback for when GTM scripts are ready */
|
|
35
|
+
onReady: (callback: (state: ScriptLoadState[]) => void) => () => void;
|
|
36
|
+
/** Whether GTM has been initialized */
|
|
37
|
+
initialized: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Consent-specific API subset.
|
|
41
|
+
*/
|
|
42
|
+
interface GtmConsentApi {
|
|
43
|
+
setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
44
|
+
updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create a GTM store for Svelte.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```svelte
|
|
51
|
+
* <script>
|
|
52
|
+
* import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';
|
|
53
|
+
* import { onMount } from 'svelte';
|
|
54
|
+
*
|
|
55
|
+
* const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });
|
|
56
|
+
* setGtmContext(gtm);
|
|
57
|
+
* </script>
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
declare function createGtmStore(options: GtmStoreOptions): Writable<GtmStoreValue>;
|
|
61
|
+
/**
|
|
62
|
+
* Get the GTM context from a parent component.
|
|
63
|
+
* Must be called during component initialization.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```svelte
|
|
67
|
+
* <script>
|
|
68
|
+
* import { getGtmContext } from '@jwiedeman/gtm-kit-svelte';
|
|
69
|
+
*
|
|
70
|
+
* const gtm = getGtmContext();
|
|
71
|
+
* $: ({ push } = $gtm);
|
|
72
|
+
* </script>
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
declare function getGtmContext(): Writable<GtmStoreValue>;
|
|
76
|
+
/**
|
|
77
|
+
* Set the GTM context for child components.
|
|
78
|
+
* Call this in your root layout or App component.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```svelte
|
|
82
|
+
* <script>
|
|
83
|
+
* import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';
|
|
84
|
+
*
|
|
85
|
+
* const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });
|
|
86
|
+
* setGtmContext(gtm);
|
|
87
|
+
* </script>
|
|
88
|
+
*
|
|
89
|
+
* <slot />
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
declare function setGtmContext(store: Writable<GtmStoreValue>): void;
|
|
93
|
+
/**
|
|
94
|
+
* Alias for getGtmContext() - get the full GTM store.
|
|
95
|
+
*/
|
|
96
|
+
declare const gtmContext: typeof getGtmContext;
|
|
97
|
+
/**
|
|
98
|
+
* Get a derived store that provides just the push function.
|
|
99
|
+
* Use this when you only need to push events.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```svelte
|
|
103
|
+
* <script>
|
|
104
|
+
* import { gtmPush } from '@jwiedeman/gtm-kit-svelte';
|
|
105
|
+
*
|
|
106
|
+
* const push = gtmPush();
|
|
107
|
+
*
|
|
108
|
+
* function handleClick() {
|
|
109
|
+
* $push({ event: 'button_click' });
|
|
110
|
+
* }
|
|
111
|
+
* </script>
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function gtmPush(): Readable<(value: DataLayerValue) => void>;
|
|
115
|
+
/**
|
|
116
|
+
* Get a derived store that provides consent functions.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```svelte
|
|
120
|
+
* <script>
|
|
121
|
+
* import { gtmConsent } from '@jwiedeman/gtm-kit-svelte';
|
|
122
|
+
*
|
|
123
|
+
* const consent = gtmConsent();
|
|
124
|
+
*
|
|
125
|
+
* function acceptAll() {
|
|
126
|
+
* $consent.updateConsent({ analytics_storage: 'granted' });
|
|
127
|
+
* }
|
|
128
|
+
* </script>
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
declare function gtmConsent(): Readable<GtmConsentApi>;
|
|
132
|
+
/**
|
|
133
|
+
* Get a derived store that provides the raw GTM client.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```svelte
|
|
137
|
+
* <script>
|
|
138
|
+
* import { gtmClient } from '@jwiedeman/gtm-kit-svelte';
|
|
139
|
+
*
|
|
140
|
+
* const client = gtmClient();
|
|
141
|
+
* </script>
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
declare function gtmClient(): Readable<GtmClient>;
|
|
145
|
+
/**
|
|
146
|
+
* Get a derived store that provides the whenReady function.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```svelte
|
|
150
|
+
* <script>
|
|
151
|
+
* import { gtmReady } from '@jwiedeman/gtm-kit-svelte';
|
|
152
|
+
* import { onMount } from 'svelte';
|
|
153
|
+
*
|
|
154
|
+
* const whenReady = gtmReady();
|
|
155
|
+
*
|
|
156
|
+
* onMount(async () => {
|
|
157
|
+
* const states = await $whenReady();
|
|
158
|
+
* console.log('GTM loaded:', states);
|
|
159
|
+
* });
|
|
160
|
+
* </script>
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
declare function gtmReady(): Readable<() => Promise<ScriptLoadState[]>>;
|
|
164
|
+
|
|
165
|
+
export { GtmConsentApi, GtmStoreOptions, GtmStoreValue, createGtmStore, getGtmContext, gtmClient, gtmConsent, gtmContext, gtmPush, gtmReady, setGtmContext };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { writable, derived } from 'svelte/store';
|
|
2
|
+
import { getContext, setContext } from 'svelte';
|
|
3
|
+
import { createGtmClient } from '@jwiedeman/gtm-kit';
|
|
4
|
+
|
|
5
|
+
var l=Symbol("gtm-kit");function G(t){let{autoInit:e=!0,onBeforeInit:r,...m}=t,o=createGtmClient(m),p=writable({client:o,push:n=>o.push(n),setConsentDefaults:(n,s)=>o.setConsentDefaults(n,s),updateConsent:(n,s)=>o.updateConsent(n,s),whenReady:()=>o.whenReady(),onReady:n=>o.onReady(n),initialized:!1});return r&&r(o),e&&(o.init(),p.update(n=>({...n,initialized:!0}))),p}function a(){let t=getContext(l);if(!t)throw new Error("[gtm-kit] getGtmContext() was called outside of a component tree with GTM context. Make sure to call setGtmContext() in a parent component.");return t}function S(t){setContext(l,t);}var f=a;function x(){let t=a();return derived(t,e=>e.push)}function g(){let t=a();return derived(t,e=>({setConsentDefaults:e.setConsentDefaults,updateConsent:e.updateConsent}))}function y(){let t=a();return derived(t,e=>e.client)}function R(){let t=a();return derived(t,e=>e.whenReady)}
|
|
6
|
+
|
|
7
|
+
export { G as createGtmStore, a as getGtmContext, y as gtmClient, g as gtmConsent, f as gtmContext, x as gtmPush, R as gtmReady, S as setGtmContext };
|
|
8
|
+
//# sourceMappingURL=out.js.map
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/store.ts"],"names":["writable","derived","getContext","setContext","createGtmClient","GTM_CONTEXT_KEY","createGtmStore","options","autoInit","onBeforeInit","clientOptions","client","store","value","state","regionOptions","callback","s","getGtmContext","context","setGtmContext","gtmContext","gtmPush","$store","gtmConsent","gtmClient","gtmReady"],"mappings":"AAAA,OAAS,YAAAA,EAAU,WAAAC,MAA6C,eAChE,OAAS,cAAAC,EAAY,cAAAC,MAAkB,SACvC,OACE,mBAAAC,MAOK,qBAiDP,IAAMC,EAAkB,OAAO,SAAS,EAgBjC,SAASC,EAAeC,EAAmD,CAChF,GAAM,CAAE,SAAAC,EAAW,GAAM,aAAAC,EAAc,GAAGC,CAAc,EAAIH,EAEtDI,EAASP,EAAgBM,CAAa,EActCE,EAAQZ,EAZsB,CAClC,OAAAW,EACA,KAAOE,GAA0BF,EAAO,KAAKE,CAAK,EAClD,mBAAoB,CAACC,EAAqBC,IACxCJ,EAAO,mBAAmBG,EAAOC,CAAa,EAChD,cAAe,CAACD,EAAqBC,IACnCJ,EAAO,cAAcG,EAAOC,CAAa,EAC3C,UAAW,IAAMJ,EAAO,UAAU,EAClC,QAAUK,GAAiDL,EAAO,QAAQK,CAAQ,EAClF,YAAa,EACf,CAEkD,EAGlD,OAAIP,GACFA,EAAaE,CAAM,EAIjBH,IACFG,EAAO,KAAK,EACZC,EAAM,OAAQK,IAAO,CAAE,GAAGA,EAAG,YAAa,EAAK,EAAE,GAG5CL,CACT,CAgBO,SAASM,GAAyC,CACvD,IAAMC,EAAUjB,EAAoCG,CAAe,EACnE,GAAI,CAACc,EACH,MAAM,IAAI,MACR,6IAEF,EAEF,OAAOA,CACT,CAkBO,SAASC,EAAcR,EAAsC,CAClET,EAAWE,EAAiBO,CAAK,CACnC,CAKO,IAAMS,EAAaH,EAmBnB,SAASI,GAAqD,CACnE,IAAMV,EAAQM,EAAc,EAC5B,OAAOjB,EAAQW,EAAQW,GAAWA,EAAO,IAAI,CAC/C,CAkBO,SAASC,GAAsC,CACpD,IAAMZ,EAAQM,EAAc,EAC5B,OAAOjB,EAAQW,EAAQW,IAAY,CACjC,mBAAoBA,EAAO,mBAC3B,cAAeA,EAAO,aACxB,EAAE,CACJ,CAcO,SAASE,GAAiC,CAC/C,IAAMb,EAAQM,EAAc,EAC5B,OAAOjB,EAAQW,EAAQW,GAAWA,EAAO,MAAM,CACjD,CAoBO,SAASG,GAAuD,CACrE,IAAMd,EAAQM,EAAc,EAC5B,OAAOjB,EAAQW,EAAQW,GAAWA,EAAO,SAAS,CACpD","sourcesContent":["import { writable, derived, type Writable, type Readable } from 'svelte/store';\nimport { getContext, setContext } from 'svelte';\nimport {\n createGtmClient,\n type ConsentRegionOptions,\n type ConsentState,\n type CreateGtmClientOptions,\n type DataLayerValue,\n type GtmClient,\n type ScriptLoadState\n} from '@jwiedeman/gtm-kit';\n\n/**\n * Options for creating a GTM store.\n * Extends CreateGtmClientOptions with Svelte-specific options.\n */\nexport interface GtmStoreOptions extends CreateGtmClientOptions {\n /**\n * Whether to automatically initialize GTM when the store is created.\n * @default true\n */\n autoInit?: boolean;\n\n /**\n * Callback executed before GTM initialization.\n * Use this to set consent defaults.\n */\n onBeforeInit?: (client: GtmClient) => void;\n}\n\n/**\n * The GTM store value containing all GTM functionality.\n */\nexport interface GtmStoreValue {\n /** The underlying GTM client instance */\n client: GtmClient;\n /** Push a value to the data layer */\n push: (value: DataLayerValue) => void;\n /** Set consent defaults (must be called before init) */\n setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;\n /** Update consent state */\n updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;\n /** Returns a promise that resolves when all GTM scripts are loaded */\n whenReady: () => Promise<ScriptLoadState[]>;\n /** Register a callback for when GTM scripts are ready */\n onReady: (callback: (state: ScriptLoadState[]) => void) => () => void;\n /** Whether GTM has been initialized */\n initialized: boolean;\n}\n\n/**\n * Consent-specific API subset.\n */\nexport interface GtmConsentApi {\n setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;\n updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;\n}\n\n/** Context key for GTM store */\nconst GTM_CONTEXT_KEY = Symbol('gtm-kit');\n\n/**\n * Create a GTM store for Svelte.\n *\n * @example\n * ```svelte\n * <script>\n * import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';\n * import { onMount } from 'svelte';\n *\n * const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });\n * setGtmContext(gtm);\n * </script>\n * ```\n */\nexport function createGtmStore(options: GtmStoreOptions): Writable<GtmStoreValue> {\n const { autoInit = true, onBeforeInit, ...clientOptions } = options;\n\n const client = createGtmClient(clientOptions);\n\n const initialValue: GtmStoreValue = {\n client,\n push: (value: DataLayerValue) => client.push(value),\n setConsentDefaults: (state: ConsentState, regionOptions?: ConsentRegionOptions) =>\n client.setConsentDefaults(state, regionOptions),\n updateConsent: (state: ConsentState, regionOptions?: ConsentRegionOptions) =>\n client.updateConsent(state, regionOptions),\n whenReady: () => client.whenReady(),\n onReady: (callback: (state: ScriptLoadState[]) => void) => client.onReady(callback),\n initialized: false\n };\n\n const store = writable<GtmStoreValue>(initialValue);\n\n // Call onBeforeInit hook if provided (for consent defaults)\n if (onBeforeInit) {\n onBeforeInit(client);\n }\n\n // Auto-initialize if enabled\n if (autoInit) {\n client.init();\n store.update((s) => ({ ...s, initialized: true }));\n }\n\n return store;\n}\n\n/**\n * Get the GTM context from a parent component.\n * Must be called during component initialization.\n *\n * @example\n * ```svelte\n * <script>\n * import { getGtmContext } from '@jwiedeman/gtm-kit-svelte';\n *\n * const gtm = getGtmContext();\n * $: ({ push } = $gtm);\n * </script>\n * ```\n */\nexport function getGtmContext(): Writable<GtmStoreValue> {\n const context = getContext<Writable<GtmStoreValue>>(GTM_CONTEXT_KEY);\n if (!context) {\n throw new Error(\n '[gtm-kit] getGtmContext() was called outside of a component tree with GTM context. ' +\n 'Make sure to call setGtmContext() in a parent component.'\n );\n }\n return context;\n}\n\n/**\n * Set the GTM context for child components.\n * Call this in your root layout or App component.\n *\n * @example\n * ```svelte\n * <script>\n * import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';\n *\n * const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });\n * setGtmContext(gtm);\n * </script>\n *\n * <slot />\n * ```\n */\nexport function setGtmContext(store: Writable<GtmStoreValue>): void {\n setContext(GTM_CONTEXT_KEY, store);\n}\n\n/**\n * Alias for getGtmContext() - get the full GTM store.\n */\nexport const gtmContext = getGtmContext;\n\n/**\n * Get a derived store that provides just the push function.\n * Use this when you only need to push events.\n *\n * @example\n * ```svelte\n * <script>\n * import { gtmPush } from '@jwiedeman/gtm-kit-svelte';\n *\n * const push = gtmPush();\n *\n * function handleClick() {\n * $push({ event: 'button_click' });\n * }\n * </script>\n * ```\n */\nexport function gtmPush(): Readable<(value: DataLayerValue) => void> {\n const store = getGtmContext();\n return derived(store, ($store) => $store.push);\n}\n\n/**\n * Get a derived store that provides consent functions.\n *\n * @example\n * ```svelte\n * <script>\n * import { gtmConsent } from '@jwiedeman/gtm-kit-svelte';\n *\n * const consent = gtmConsent();\n *\n * function acceptAll() {\n * $consent.updateConsent({ analytics_storage: 'granted' });\n * }\n * </script>\n * ```\n */\nexport function gtmConsent(): Readable<GtmConsentApi> {\n const store = getGtmContext();\n return derived(store, ($store) => ({\n setConsentDefaults: $store.setConsentDefaults,\n updateConsent: $store.updateConsent\n }));\n}\n\n/**\n * Get a derived store that provides the raw GTM client.\n *\n * @example\n * ```svelte\n * <script>\n * import { gtmClient } from '@jwiedeman/gtm-kit-svelte';\n *\n * const client = gtmClient();\n * </script>\n * ```\n */\nexport function gtmClient(): Readable<GtmClient> {\n const store = getGtmContext();\n return derived(store, ($store) => $store.client);\n}\n\n/**\n * Get a derived store that provides the whenReady function.\n *\n * @example\n * ```svelte\n * <script>\n * import { gtmReady } from '@jwiedeman/gtm-kit-svelte';\n * import { onMount } from 'svelte';\n *\n * const whenReady = gtmReady();\n *\n * onMount(async () => {\n * const states = await $whenReady();\n * console.log('GTM loaded:', states);\n * });\n * </script>\n * ```\n */\nexport function gtmReady(): Readable<() => Promise<ScriptLoadState[]>> {\n const store = getGtmContext();\n return derived(store, ($store) => $store.whenReady);\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jwiedeman/gtm-kit-svelte",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Svelte stores and actions for GTM Kit - Google Tag Manager integration.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/jwiedeman/GTM-Kit.git",
|
|
8
|
+
"directory": "packages/svelte"
|
|
9
|
+
},
|
|
10
|
+
"author": "jwiedeman",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"gtm",
|
|
13
|
+
"google-tag-manager",
|
|
14
|
+
"svelte",
|
|
15
|
+
"stores"
|
|
16
|
+
],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "dist/index.cjs",
|
|
23
|
+
"module": "dist/index.js",
|
|
24
|
+
"types": "dist/index.d.ts",
|
|
25
|
+
"svelte": "./dist/index.js",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"svelte": "./dist/index.js",
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"require": "./dist/index.cjs"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup",
|
|
39
|
+
"clean": "rm -rf dist",
|
|
40
|
+
"lint": "eslint --max-warnings=0 \"src/**/*.{ts,tsx}\"",
|
|
41
|
+
"test": "jest --config ./jest.config.cjs --runInBand --passWithNoTests",
|
|
42
|
+
"typecheck": "tsc --noEmit"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@jwiedeman/gtm-kit": "^1.0.1"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"svelte": "^4.0.0 || ^5.0.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@testing-library/svelte": "^5.2.0",
|
|
52
|
+
"svelte": "^4.2.18",
|
|
53
|
+
"svelte-jester": "^5.0.0",
|
|
54
|
+
"tslib": "^2.6.2"
|
|
55
|
+
}
|
|
56
|
+
}
|