@lalternative/nakoda-sdk-browser 0.1.0 → 0.2.0
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/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
interface NakodaOptions {
|
|
2
|
-
/** The app's public site key, shown on its page in nakoda. */
|
|
3
|
-
site: string;
|
|
4
2
|
/** nakoda's origin; https://nakoda.club by default. */
|
|
5
3
|
endpoint?: string;
|
|
4
|
+
/** @deprecated nakoda knows the app by the page's domain; ignored. */
|
|
5
|
+
site?: string;
|
|
6
6
|
}
|
|
7
7
|
/** Where the visit started, kept for the visit so a sign-up can say it. */
|
|
8
8
|
interface VisitSource {
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ function readSource(storage2) {
|
|
|
13
13
|
return null;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
function createTracker(options, env) {
|
|
16
|
+
function createTracker(options = {}, env) {
|
|
17
17
|
const endpoint = (options.endpoint ?? DEFAULT_ENDPOINT).replace(/\/$/, "") + "/v1/hit";
|
|
18
18
|
let previous = null;
|
|
19
19
|
if (!readSource(env.storage)) {
|
|
@@ -28,7 +28,7 @@ function createTracker(options, env) {
|
|
|
28
28
|
if (href === previous || isLocal(env.hostname())) return;
|
|
29
29
|
const referrer = previous ?? env.referrer;
|
|
30
30
|
previous = href;
|
|
31
|
-
env.send(endpoint, JSON.stringify({
|
|
31
|
+
env.send(endpoint, JSON.stringify({ u: href, r: referrer }));
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
34
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tracker.ts","../src/index.ts"],"sourcesContent":["export interface NakodaOptions {\n /**
|
|
1
|
+
{"version":3,"sources":["../src/tracker.ts","../src/index.ts"],"sourcesContent":["export interface NakodaOptions {\n /** nakoda's origin; https://nakoda.club by default. */\n endpoint?: string;\n /** @deprecated nakoda knows the app by the page's domain; ignored. */\n site?: string;\n}\n\n/** Where the visit started, kept for the visit so a sign-up can say it. */\nexport interface VisitSource {\n landing: string;\n referrer: string;\n}\n\nexport interface TrackerEnv {\n href: () => string;\n hostname: () => string;\n referrer: string;\n send: (url: string, body: string) => void;\n storage?: Pick<Storage, 'getItem' | 'setItem'>;\n}\n\nconst DEFAULT_ENDPOINT = 'https://nakoda.club';\nconst SOURCE_KEY = 'nakoda.source';\nconst LOCAL_HOSTS = ['localhost', '127.0.0.1', '[::1]'];\n\nexport function isLocal(hostname: string): boolean {\n return LOCAL_HOSTS.includes(hostname) || hostname.endsWith('.localhost');\n}\n\nexport function readSource(storage: TrackerEnv['storage']): VisitSource | null {\n try {\n const raw = storage?.getItem(SOURCE_KEY);\n return raw ? (JSON.parse(raw) as VisitSource) : null;\n } catch {\n return null;\n }\n}\n\n/**\n * A tracker sends one page view per distinct URL. The first carries the\n * page's referrer; the next ones, the previous URL of the same site, which\n * nakoda reads as the same visit going on.\n */\nexport function createTracker(options: NakodaOptions = {}, env: TrackerEnv) {\n const endpoint = (options.endpoint ?? DEFAULT_ENDPOINT).replace(/\\/$/, '') + '/v1/hit';\n let previous: string | null = null;\n\n if (!readSource(env.storage)) {\n try {\n env.storage?.setItem(SOURCE_KEY, JSON.stringify({ landing: env.href(), referrer: env.referrer }));\n } catch {\n // A browser that refuses storage still counts its page views.\n }\n }\n\n return {\n pageview(): void {\n const href = env.href();\n if (href === previous || isLocal(env.hostname())) return;\n const referrer = previous ?? env.referrer;\n previous = href;\n env.send(endpoint, JSON.stringify({ u: href, r: referrer }));\n },\n };\n}\n","import { createTracker, readSource } from './tracker.ts';\nimport type { NakodaOptions, VisitSource } from './tracker.ts';\n\nexport type { NakodaOptions, VisitSource };\n\nfunction send(url: string, body: string): void {\n // text/plain keeps the request simple: no CORS preflight, and sendBeacon\n // outlives the page being left.\n const blob = new Blob([body], { type: 'text/plain' });\n if (navigator.sendBeacon?.(url, blob)) return;\n void fetch(url, { method: 'POST', body, keepalive: true, headers: { 'content-type': 'text/plain' } }).catch(\n () => undefined,\n );\n}\n\nfunction storage(): Storage | undefined {\n try {\n return window.sessionStorage;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Counts the page's views with nakoda, the History API's navigations\n * included, and keeps where the visit came from. Returns what stops it.\n */\nexport function init(options: NakodaOptions): () => void {\n if (typeof window === 'undefined') return () => undefined;\n const tracker = createTracker(options, {\n href: () => location.href,\n hostname: () => location.hostname,\n referrer: document.referrer,\n send,\n storage: storage(),\n });\n tracker.pageview();\n\n const pushState = history.pushState;\n const replaceState = history.replaceState;\n history.pushState = function (this: History, ...args: Parameters<History['pushState']>) {\n pushState.apply(this, args);\n tracker.pageview();\n };\n history.replaceState = function (this: History, ...args: Parameters<History['replaceState']>) {\n replaceState.apply(this, args);\n tracker.pageview();\n };\n const onPop = () => tracker.pageview();\n window.addEventListener('popstate', onPop);\n\n return () => {\n history.pushState = pushState;\n history.replaceState = replaceState;\n window.removeEventListener('popstate', onPop);\n };\n}\n\n/** Where the current visit started: the landing URL and its referrer. */\nexport function getSource(): VisitSource | null {\n if (typeof window === 'undefined') return null;\n return readSource(storage());\n}\n"],"mappings":";AAqBA,IAAM,mBAAmB;AACzB,IAAM,aAAa;AACnB,IAAM,cAAc,CAAC,aAAa,aAAa,OAAO;AAE/C,SAAS,QAAQ,UAA2B;AACjD,SAAO,YAAY,SAAS,QAAQ,KAAK,SAAS,SAAS,YAAY;AACzE;AAEO,SAAS,WAAWA,UAAoD;AAC7E,MAAI;AACF,UAAM,MAAMA,UAAS,QAAQ,UAAU;AACvC,WAAO,MAAO,KAAK,MAAM,GAAG,IAAoB;AAAA,EAClD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOO,SAAS,cAAc,UAAyB,CAAC,GAAG,KAAiB;AAC1E,QAAM,YAAY,QAAQ,YAAY,kBAAkB,QAAQ,OAAO,EAAE,IAAI;AAC7E,MAAI,WAA0B;AAE9B,MAAI,CAAC,WAAW,IAAI,OAAO,GAAG;AAC5B,QAAI;AACF,UAAI,SAAS,QAAQ,YAAY,KAAK,UAAU,EAAE,SAAS,IAAI,KAAK,GAAG,UAAU,IAAI,SAAS,CAAC,CAAC;AAAA,IAClG,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AAAA,IACL,WAAiB;AACf,YAAM,OAAO,IAAI,KAAK;AACtB,UAAI,SAAS,YAAY,QAAQ,IAAI,SAAS,CAAC,EAAG;AAClD,YAAM,WAAW,YAAY,IAAI;AACjC,iBAAW;AACX,UAAI,KAAK,UAAU,KAAK,UAAU,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;AAAA,IAC7D;AAAA,EACF;AACF;;;AC3DA,SAAS,KAAK,KAAa,MAAoB;AAG7C,QAAM,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,aAAa,CAAC;AACpD,MAAI,UAAU,aAAa,KAAK,IAAI,EAAG;AACvC,OAAK,MAAM,KAAK,EAAE,QAAQ,QAAQ,MAAM,WAAW,MAAM,SAAS,EAAE,gBAAgB,aAAa,EAAE,CAAC,EAAE;AAAA,IACpG,MAAM;AAAA,EACR;AACF;AAEA,SAAS,UAA+B;AACtC,MAAI;AACF,WAAO,OAAO;AAAA,EAChB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,SAAS,KAAK,SAAoC;AACvD,MAAI,OAAO,WAAW,YAAa,QAAO,MAAM;AAChD,QAAM,UAAU,cAAc,SAAS;AAAA,IACrC,MAAM,MAAM,SAAS;AAAA,IACrB,UAAU,MAAM,SAAS;AAAA,IACzB,UAAU,SAAS;AAAA,IACnB;AAAA,IACA,SAAS,QAAQ;AAAA,EACnB,CAAC;AACD,UAAQ,SAAS;AAEjB,QAAM,YAAY,QAAQ;AAC1B,QAAM,eAAe,QAAQ;AAC7B,UAAQ,YAAY,YAA4B,MAAwC;AACtF,cAAU,MAAM,MAAM,IAAI;AAC1B,YAAQ,SAAS;AAAA,EACnB;AACA,UAAQ,eAAe,YAA4B,MAA2C;AAC5F,iBAAa,MAAM,MAAM,IAAI;AAC7B,YAAQ,SAAS;AAAA,EACnB;AACA,QAAM,QAAQ,MAAM,QAAQ,SAAS;AACrC,SAAO,iBAAiB,YAAY,KAAK;AAEzC,SAAO,MAAM;AACX,YAAQ,YAAY;AACpB,YAAQ,eAAe;AACvB,WAAO,oBAAoB,YAAY,KAAK;AAAA,EAC9C;AACF;AAGO,SAAS,YAAgC;AAC9C,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,SAAO,WAAW,QAAQ,CAAC;AAC7B;","names":["storage"]}
|
package/package.json
CHANGED