@walkeros/web-source-session 1.1.2 → 1.1.4-next-1771252576264
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/dev.js +1 -58
- package/dist/dev.mjs +1 -35
- package/dist/dev.mjs.map +1 -1
- package/dist/index.js +1 -259
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -233
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +83 -0
- package/package.json +15 -7
- package/dist/chunk-J5LGTIGS.mjs +0 -10
- package/dist/chunk-J5LGTIGS.mjs.map +0 -1
package/dist/dev.js
CHANGED
|
@@ -1,58 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/dev.ts
|
|
21
|
-
var dev_exports = {};
|
|
22
|
-
__export(dev_exports, {
|
|
23
|
-
schemas: () => schemas_exports
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(dev_exports);
|
|
26
|
-
|
|
27
|
-
// src/schemas/index.ts
|
|
28
|
-
var schemas_exports = {};
|
|
29
|
-
__export(schemas_exports, {
|
|
30
|
-
SettingsSchema: () => SettingsSchema,
|
|
31
|
-
settings: () => settings
|
|
32
|
-
});
|
|
33
|
-
var import_dev2 = require("@walkeros/core/dev");
|
|
34
|
-
|
|
35
|
-
// src/schemas/settings.ts
|
|
36
|
-
var import_dev = require("@walkeros/core/dev");
|
|
37
|
-
var SettingsSchema = import_dev.z.object({
|
|
38
|
-
storage: import_dev.z.boolean().default(false).describe("Enable persistent storage for session/device IDs").optional(),
|
|
39
|
-
consent: import_dev.z.union([import_dev.z.string(), import_dev.z.array(import_dev.z.string())]).describe("Consent key(s) required to enable storage mode").optional(),
|
|
40
|
-
length: import_dev.z.number().default(30).describe("Session timeout in minutes").optional(),
|
|
41
|
-
pulse: import_dev.z.boolean().default(false).describe("Keep session alive on each event").optional(),
|
|
42
|
-
sessionKey: import_dev.z.string().default("elbSessionId").describe("Storage key for session ID").optional(),
|
|
43
|
-
sessionStorage: import_dev.z.enum(["local", "session"]).default("local").describe("Storage type for session").optional(),
|
|
44
|
-
deviceKey: import_dev.z.string().default("elbDeviceId").describe("Storage key for device ID").optional(),
|
|
45
|
-
deviceStorage: import_dev.z.enum(["local", "session"]).default("local").describe("Storage type for device").optional(),
|
|
46
|
-
deviceAge: import_dev.z.number().default(30).describe("Device ID age in days").optional(),
|
|
47
|
-
// Note: Using z.any() because z.custom() cannot be converted to JSON Schema
|
|
48
|
-
// TypeScript types provide compile-time safety; runtime accepts function or false
|
|
49
|
-
cb: import_dev.z.any().describe("Custom session callback function or false to disable").optional()
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// src/schemas/index.ts
|
|
53
|
-
var settings = (0, import_dev2.zodToSchema)(SettingsSchema);
|
|
54
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
55
|
-
0 && (module.exports = {
|
|
56
|
-
schemas
|
|
57
|
-
});
|
|
58
|
-
//# sourceMappingURL=dev.js.map
|
|
1
|
+
"use strict";var e,o=Object.defineProperty,t=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,i=(e,t)=>{for(var s in t)o(e,s,{get:t[s],enumerable:!0})},a={};i(a,{schemas:()=>n}),module.exports=(e=a,((e,i,a,n)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let l of s(i))r.call(e,l)||l===a||o(e,l,{get:()=>i[l],enumerable:!(n=t(i,l))||n.enumerable});return e})(o({},"__esModule",{value:!0}),e));var n={};i(n,{SettingsSchema:()=>d,settings:()=>b});var l=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),d=c.z.object({storage:c.z.boolean().default(!1).describe("Enable persistent storage for session/device IDs").optional(),consent:c.z.union([c.z.string(),c.z.array(c.z.string())]).describe("Consent key(s) required to enable storage mode").optional(),length:c.z.number().default(30).describe("Session timeout in minutes").optional(),pulse:c.z.boolean().default(!1).describe("Keep session alive on each event").optional(),sessionKey:c.z.string().default("elbSessionId").describe("Storage key for session ID").optional(),sessionStorage:c.z.enum(["local","session"]).default("local").describe("Storage type for session").optional(),deviceKey:c.z.string().default("elbDeviceId").describe("Storage key for device ID").optional(),deviceStorage:c.z.enum(["local","session"]).default("local").describe("Storage type for device").optional(),deviceAge:c.z.number().default(30).describe("Device ID age in days").optional(),cb:c.z.any().describe("Custom session callback function or false to disable").optional()}),b=(0,l.zodToSchema)(d);//# sourceMappingURL=dev.js.map
|
package/dist/dev.mjs
CHANGED
|
@@ -1,35 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__export
|
|
3
|
-
} from "./chunk-J5LGTIGS.mjs";
|
|
4
|
-
|
|
5
|
-
// src/schemas/index.ts
|
|
6
|
-
var schemas_exports = {};
|
|
7
|
-
__export(schemas_exports, {
|
|
8
|
-
SettingsSchema: () => SettingsSchema,
|
|
9
|
-
settings: () => settings
|
|
10
|
-
});
|
|
11
|
-
import { zodToSchema } from "@walkeros/core/dev";
|
|
12
|
-
|
|
13
|
-
// src/schemas/settings.ts
|
|
14
|
-
import { z } from "@walkeros/core/dev";
|
|
15
|
-
var SettingsSchema = z.object({
|
|
16
|
-
storage: z.boolean().default(false).describe("Enable persistent storage for session/device IDs").optional(),
|
|
17
|
-
consent: z.union([z.string(), z.array(z.string())]).describe("Consent key(s) required to enable storage mode").optional(),
|
|
18
|
-
length: z.number().default(30).describe("Session timeout in minutes").optional(),
|
|
19
|
-
pulse: z.boolean().default(false).describe("Keep session alive on each event").optional(),
|
|
20
|
-
sessionKey: z.string().default("elbSessionId").describe("Storage key for session ID").optional(),
|
|
21
|
-
sessionStorage: z.enum(["local", "session"]).default("local").describe("Storage type for session").optional(),
|
|
22
|
-
deviceKey: z.string().default("elbDeviceId").describe("Storage key for device ID").optional(),
|
|
23
|
-
deviceStorage: z.enum(["local", "session"]).default("local").describe("Storage type for device").optional(),
|
|
24
|
-
deviceAge: z.number().default(30).describe("Device ID age in days").optional(),
|
|
25
|
-
// Note: Using z.any() because z.custom() cannot be converted to JSON Schema
|
|
26
|
-
// TypeScript types provide compile-time safety; runtime accepts function or false
|
|
27
|
-
cb: z.any().describe("Custom session callback function or false to disable").optional()
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
// src/schemas/index.ts
|
|
31
|
-
var settings = zodToSchema(SettingsSchema);
|
|
32
|
-
export {
|
|
33
|
-
schemas_exports as schemas
|
|
34
|
-
};
|
|
35
|
-
//# sourceMappingURL=dev.mjs.map
|
|
1
|
+
var e=Object.defineProperty,o={};((o,s)=>{for(var i in s)e(o,i,{get:s[i],enumerable:!0})})(o,{SettingsSchema:()=>t,settings:()=>a});import{zodToSchema as s}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";var t=i.object({storage:i.boolean().default(!1).describe("Enable persistent storage for session/device IDs").optional(),consent:i.union([i.string(),i.array(i.string())]).describe("Consent key(s) required to enable storage mode").optional(),length:i.number().default(30).describe("Session timeout in minutes").optional(),pulse:i.boolean().default(!1).describe("Keep session alive on each event").optional(),sessionKey:i.string().default("elbSessionId").describe("Storage key for session ID").optional(),sessionStorage:i.enum(["local","session"]).default("local").describe("Storage type for session").optional(),deviceKey:i.string().default("elbDeviceId").describe("Storage key for device ID").optional(),deviceStorage:i.enum(["local","session"]).default("local").describe("Storage type for device").optional(),deviceAge:i.number().default(30).describe("Device ID age in days").optional(),cb:i.any().describe("Custom session callback function or false to disable").optional()}),a=s(t);export{o as schemas};//# sourceMappingURL=dev.mjs.map
|
package/dist/dev.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Session source settings schema\n */\nexport const SettingsSchema = z.object({\n storage: z\n .boolean()\n .default(false)\n .describe('Enable persistent storage for session/device IDs')\n .optional(),\n\n consent: z\n .union([z.string(), z.array(z.string())])\n .describe('Consent key(s) required to enable storage mode')\n .optional(),\n\n length: z\n .number()\n .default(30)\n .describe('Session timeout in minutes')\n .optional(),\n\n pulse: z\n .boolean()\n .default(false)\n .describe('Keep session alive on each event')\n .optional(),\n\n sessionKey: z\n .string()\n .default('elbSessionId')\n .describe('Storage key for session ID')\n .optional(),\n\n sessionStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for session')\n .optional(),\n\n deviceKey: z\n .string()\n .default('elbDeviceId')\n .describe('Storage key for device ID')\n .optional(),\n\n deviceStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for device')\n .optional(),\n\n deviceAge: z\n .number()\n .default(30)\n .describe('Device ID age in days')\n .optional(),\n\n // Note: Using z.any() because z.custom() cannot be converted to JSON Schema\n // TypeScript types provide compile-time safety; runtime accepts function or false\n cb: z\n .any()\n .describe('Custom session callback function or false to disable')\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Session source settings schema\n */\nexport const SettingsSchema = z.object({\n storage: z\n .boolean()\n .default(false)\n .describe('Enable persistent storage for session/device IDs')\n .optional(),\n\n consent: z\n .union([z.string(), z.array(z.string())])\n .describe('Consent key(s) required to enable storage mode')\n .optional(),\n\n length: z\n .number()\n .default(30)\n .describe('Session timeout in minutes')\n .optional(),\n\n pulse: z\n .boolean()\n .default(false)\n .describe('Keep session alive on each event')\n .optional(),\n\n sessionKey: z\n .string()\n .default('elbSessionId')\n .describe('Storage key for session ID')\n .optional(),\n\n sessionStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for session')\n .optional(),\n\n deviceKey: z\n .string()\n .default('elbDeviceId')\n .describe('Storage key for device ID')\n .optional(),\n\n deviceStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for device')\n .optional(),\n\n deviceAge: z\n .number()\n .default(30)\n .describe('Device ID age in days')\n .optional(),\n\n // Note: Using z.any() because z.custom() cannot be converted to JSON Schema\n // TypeScript types provide compile-time safety; runtime accepts function or false\n cb: z\n .any()\n .describe('Custom session callback function or false to disable')\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n"],"mappings":";;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,mBAAmB;;;ACA5B,SAAS,SAAS;AAKX,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,SAAS,EACN,QAAQ,EACR,QAAQ,KAAK,EACb,SAAS,kDAAkD,EAC3D,SAAS;AAAA,EAEZ,SAAS,EACN,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EACvC,SAAS,gDAAgD,EACzD,SAAS;AAAA,EAEZ,QAAQ,EACL,OAAO,EACP,QAAQ,EAAE,EACV,SAAS,4BAA4B,EACrC,SAAS;AAAA,EAEZ,OAAO,EACJ,QAAQ,EACR,QAAQ,KAAK,EACb,SAAS,kCAAkC,EAC3C,SAAS;AAAA,EAEZ,YAAY,EACT,OAAO,EACP,QAAQ,cAAc,EACtB,SAAS,4BAA4B,EACrC,SAAS;AAAA,EAEZ,gBAAgB,EACb,KAAK,CAAC,SAAS,SAAS,CAAC,EACzB,QAAQ,OAAO,EACf,SAAS,0BAA0B,EACnC,SAAS;AAAA,EAEZ,WAAW,EACR,OAAO,EACP,QAAQ,aAAa,EACrB,SAAS,2BAA2B,EACpC,SAAS;AAAA,EAEZ,eAAe,EACZ,KAAK,CAAC,SAAS,SAAS,CAAC,EACzB,QAAQ,OAAO,EACf,SAAS,yBAAyB,EAClC,SAAS;AAAA,EAEZ,WAAW,EACR,OAAO,EACP,QAAQ,EAAE,EACV,SAAS,uBAAuB,EAChC,SAAS;AAAA;AAAA;AAAA,EAIZ,IAAI,EACD,IAAI,EACJ,SAAS,sDAAsD,EAC/D,SAAS;AACd,CAAC;;;AD1DM,IAAM,WAAW,YAAY,cAAc;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -1,259 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
SourceSession: () => types_exports,
|
|
24
|
-
default: () => index_default,
|
|
25
|
-
sessionStart: () => sessionStart,
|
|
26
|
-
sessionStorage: () => sessionStorage,
|
|
27
|
-
sessionWindow: () => sessionWindow,
|
|
28
|
-
sourceSession: () => sourceSession
|
|
29
|
-
});
|
|
30
|
-
module.exports = __toCommonJS(index_exports);
|
|
31
|
-
|
|
32
|
-
// src/lib/sessionStorage.ts
|
|
33
|
-
var import_core2 = require("@walkeros/core");
|
|
34
|
-
var import_web_core = require("@walkeros/web-core");
|
|
35
|
-
|
|
36
|
-
// src/lib/sessionWindow.ts
|
|
37
|
-
var import_core = require("@walkeros/core");
|
|
38
|
-
function sessionWindow(config = {}) {
|
|
39
|
-
let isStart = config.isStart || false;
|
|
40
|
-
const known = { isStart, storage: false };
|
|
41
|
-
if (config.isStart === false) return known;
|
|
42
|
-
if (!isStart) {
|
|
43
|
-
const [perf] = performance.getEntriesByType(
|
|
44
|
-
"navigation"
|
|
45
|
-
);
|
|
46
|
-
if (perf.type !== "navigate") return known;
|
|
47
|
-
}
|
|
48
|
-
const url = new URL(config.url || window.location.href);
|
|
49
|
-
const ref = config.referrer || document.referrer;
|
|
50
|
-
const referrer = ref && new URL(ref).hostname;
|
|
51
|
-
const marketing = (0, import_core.getMarketingParameters)(url, config.parameters);
|
|
52
|
-
if (Object.keys(marketing).length) {
|
|
53
|
-
if (!marketing.marketing)
|
|
54
|
-
marketing.marketing = true;
|
|
55
|
-
isStart = true;
|
|
56
|
-
}
|
|
57
|
-
if (!isStart) {
|
|
58
|
-
const domains = config.domains || [];
|
|
59
|
-
domains.push(url.hostname);
|
|
60
|
-
isStart = !domains.includes(referrer);
|
|
61
|
-
}
|
|
62
|
-
return isStart ? (
|
|
63
|
-
// It's a session start, moin
|
|
64
|
-
Object.assign(
|
|
65
|
-
{
|
|
66
|
-
isStart,
|
|
67
|
-
storage: false,
|
|
68
|
-
start: Date.now(),
|
|
69
|
-
id: (0, import_core.getId)(12),
|
|
70
|
-
referrer
|
|
71
|
-
},
|
|
72
|
-
marketing,
|
|
73
|
-
config.data
|
|
74
|
-
)
|
|
75
|
-
) : (
|
|
76
|
-
// No session start
|
|
77
|
-
known
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// src/lib/sessionStorage.ts
|
|
82
|
-
function sessionStorage(config = {}) {
|
|
83
|
-
const now = Date.now();
|
|
84
|
-
const {
|
|
85
|
-
length = 30,
|
|
86
|
-
// Session length in minutes
|
|
87
|
-
deviceKey = "elbDeviceId",
|
|
88
|
-
deviceStorage = "local",
|
|
89
|
-
deviceAge = 30,
|
|
90
|
-
// Device ID age in days
|
|
91
|
-
sessionKey = "elbSessionId",
|
|
92
|
-
sessionStorage: sessionStorage2 = "local",
|
|
93
|
-
pulse = false
|
|
94
|
-
// Handle the counting
|
|
95
|
-
} = config;
|
|
96
|
-
const windowSession = sessionWindow(config);
|
|
97
|
-
let isStart = false;
|
|
98
|
-
const device = (0, import_core2.tryCatch)((key, age, storage) => {
|
|
99
|
-
let id = (0, import_web_core.storageRead)(key, storage);
|
|
100
|
-
if (!id) {
|
|
101
|
-
id = (0, import_core2.getId)(8);
|
|
102
|
-
(0, import_web_core.storageWrite)(key, id, age * 1440, storage);
|
|
103
|
-
}
|
|
104
|
-
return String(id);
|
|
105
|
-
})(deviceKey, deviceAge, deviceStorage);
|
|
106
|
-
const existingSession = (0, import_core2.tryCatch)(
|
|
107
|
-
(key, storage) => {
|
|
108
|
-
const session2 = JSON.parse(String((0, import_web_core.storageRead)(key, storage)));
|
|
109
|
-
if (pulse) return session2;
|
|
110
|
-
session2.isNew = false;
|
|
111
|
-
if (windowSession.marketing) {
|
|
112
|
-
Object.assign(session2, windowSession);
|
|
113
|
-
isStart = true;
|
|
114
|
-
}
|
|
115
|
-
if (isStart || session2.updated + length * 6e4 < now) {
|
|
116
|
-
delete session2.id;
|
|
117
|
-
delete session2.referrer;
|
|
118
|
-
session2.start = now;
|
|
119
|
-
session2.count++;
|
|
120
|
-
session2.runs = 1;
|
|
121
|
-
isStart = true;
|
|
122
|
-
} else {
|
|
123
|
-
session2.runs++;
|
|
124
|
-
}
|
|
125
|
-
return session2;
|
|
126
|
-
},
|
|
127
|
-
() => {
|
|
128
|
-
isStart = true;
|
|
129
|
-
}
|
|
130
|
-
)(sessionKey, sessionStorage2) || {};
|
|
131
|
-
const defaultSession = {
|
|
132
|
-
id: (0, import_core2.getId)(12),
|
|
133
|
-
start: now,
|
|
134
|
-
isNew: true,
|
|
135
|
-
count: 1,
|
|
136
|
-
runs: 1
|
|
137
|
-
};
|
|
138
|
-
const session = Object.assign(
|
|
139
|
-
defaultSession,
|
|
140
|
-
// Default session values
|
|
141
|
-
windowSession,
|
|
142
|
-
// Basic session data based on window
|
|
143
|
-
existingSession,
|
|
144
|
-
// (Updated) existing session
|
|
145
|
-
{ device },
|
|
146
|
-
// Device ID
|
|
147
|
-
{ isStart, storage: true, updated: now },
|
|
148
|
-
// Status of the session
|
|
149
|
-
config.data
|
|
150
|
-
// Given data has the highest priority
|
|
151
|
-
);
|
|
152
|
-
(0, import_web_core.storageWrite)(sessionKey, JSON.stringify(session), length * 2, sessionStorage2);
|
|
153
|
-
return session;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// src/lib/sessionStart.ts
|
|
157
|
-
var import_core3 = require("@walkeros/core");
|
|
158
|
-
function sessionStart(config = {}) {
|
|
159
|
-
const { cb, consent, collector, storage } = config;
|
|
160
|
-
const sessionFn = storage ? sessionStorage : sessionWindow;
|
|
161
|
-
if (consent) {
|
|
162
|
-
const consentHandler = onConsentFn(config, cb);
|
|
163
|
-
const consentConfig = ((0, import_core3.isArray)(consent) ? consent : [consent]).reduce(
|
|
164
|
-
(acc, key) => ({ ...acc, [key]: consentHandler }),
|
|
165
|
-
{}
|
|
166
|
-
);
|
|
167
|
-
if (collector) {
|
|
168
|
-
collector.command("on", "consent", consentConfig);
|
|
169
|
-
}
|
|
170
|
-
} else {
|
|
171
|
-
return callFuncAndCb(sessionFn(config), collector, cb);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
function callFuncAndCb(session, collector, cb) {
|
|
175
|
-
if (cb === false) return session;
|
|
176
|
-
if (!cb) cb = defaultCb;
|
|
177
|
-
return cb(session, collector, defaultCb);
|
|
178
|
-
}
|
|
179
|
-
function onConsentFn(config, cb) {
|
|
180
|
-
let lastProcessedGroup;
|
|
181
|
-
const func = (collector, consent) => {
|
|
182
|
-
if ((0, import_core3.isDefined)(lastProcessedGroup) && lastProcessedGroup === (collector == null ? void 0 : collector.group))
|
|
183
|
-
return;
|
|
184
|
-
lastProcessedGroup = collector == null ? void 0 : collector.group;
|
|
185
|
-
let sessionFn = () => sessionWindow(config);
|
|
186
|
-
if (config.consent) {
|
|
187
|
-
const consentKeys = ((0, import_core3.isArray)(config.consent) ? config.consent : [config.consent]).reduce((acc, key) => ({ ...acc, [key]: true }), {});
|
|
188
|
-
if ((0, import_core3.getGrantedConsent)(consentKeys, consent))
|
|
189
|
-
sessionFn = () => sessionStorage(config);
|
|
190
|
-
}
|
|
191
|
-
return callFuncAndCb(sessionFn(), collector, cb);
|
|
192
|
-
};
|
|
193
|
-
return func;
|
|
194
|
-
}
|
|
195
|
-
var defaultCb = (session, collector) => {
|
|
196
|
-
const user = {};
|
|
197
|
-
if (session.id) user.session = session.id;
|
|
198
|
-
if (session.storage && session.device) user.device = session.device;
|
|
199
|
-
if (collector) {
|
|
200
|
-
collector.command("user", user);
|
|
201
|
-
}
|
|
202
|
-
if (session.isStart) {
|
|
203
|
-
if (collector) {
|
|
204
|
-
collector.push({
|
|
205
|
-
name: "session start",
|
|
206
|
-
data: session
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return session;
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
// src/types/index.ts
|
|
214
|
-
var types_exports = {};
|
|
215
|
-
|
|
216
|
-
// src/index.ts
|
|
217
|
-
var sourceSession = async (context) => {
|
|
218
|
-
const { config, env } = context;
|
|
219
|
-
const { elb, command } = env;
|
|
220
|
-
const settings = {
|
|
221
|
-
...config == null ? void 0 : config.settings
|
|
222
|
-
};
|
|
223
|
-
const fullConfig = {
|
|
224
|
-
settings
|
|
225
|
-
};
|
|
226
|
-
const collectorInterface = {
|
|
227
|
-
push: elb,
|
|
228
|
-
group: void 0,
|
|
229
|
-
command
|
|
230
|
-
};
|
|
231
|
-
sessionStart({
|
|
232
|
-
...settings,
|
|
233
|
-
collector: collectorInterface
|
|
234
|
-
});
|
|
235
|
-
const handleEvent = async (event) => {
|
|
236
|
-
if (event === "consent") {
|
|
237
|
-
sessionStart({
|
|
238
|
-
...settings,
|
|
239
|
-
collector: collectorInterface
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
return {
|
|
244
|
-
type: "session",
|
|
245
|
-
config: fullConfig,
|
|
246
|
-
push: elb,
|
|
247
|
-
on: handleEvent
|
|
248
|
-
};
|
|
249
|
-
};
|
|
250
|
-
var index_default = sourceSession;
|
|
251
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
252
|
-
0 && (module.exports = {
|
|
253
|
-
SourceSession,
|
|
254
|
-
sessionStart,
|
|
255
|
-
sessionStorage,
|
|
256
|
-
sessionWindow,
|
|
257
|
-
sourceSession
|
|
258
|
-
});
|
|
259
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,r=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,o={};((e,r)=>{for(var n in r)t(e,n,{get:r[n],enumerable:!0})})(o,{SourceSession:()=>p,default:()=>y,sessionStart:()=>g,sessionStorage:()=>d,sessionWindow:()=>u,sourceSession:()=>v}),module.exports=(e=o,((e,o,i,a)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let c of n(o))s.call(e,c)||c===i||t(e,c,{get:()=>o[c],enumerable:!(a=r(o,c))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var i=require("@walkeros/core"),a=require("@walkeros/web-core"),c=require("@walkeros/core");function u(e={}){let t=e.isStart||!1;const r={isStart:t,storage:!1};if(!1===e.isStart)return r;if(!t){const[e]=performance.getEntriesByType("navigation");if("navigate"!==e.type)return r}const n=new URL(e.url||window.location.href),s=e.referrer||document.referrer,o=s&&new URL(s).hostname,i=(0,c.getMarketingParameters)(n,e.parameters);if(Object.keys(i).length&&(i.marketing||(i.marketing=!0),t=!0),!t){const r=e.domains||[];r.push(n.hostname),t=!r.includes(o)}return t?Object.assign({isStart:t,storage:!1,start:Date.now(),id:(0,c.getId)(12),referrer:o},i,e.data):r}function d(e={}){const t=Date.now(),{length:r=30,deviceKey:n="elbDeviceId",deviceStorage:s="local",deviceAge:o=30,sessionKey:c="elbSessionId",sessionStorage:d="local",pulse:l=!1}=e,g=u(e);let f=!1;const m=(0,i.tryCatch)((e,t,r)=>{let n=(0,a.storageRead)(e,r);return n||(n=(0,i.getId)(8),(0,a.storageWrite)(e,n,1440*t,r)),String(n)})(n,o,s),p=(0,i.tryCatch)((e,n)=>{const s=JSON.parse(String((0,a.storageRead)(e,n)));return l||(s.isNew=!1,g.marketing&&(Object.assign(s,g),f=!0),f||s.updated+6e4*r<t?(delete s.id,delete s.referrer,s.start=t,s.count++,s.runs=1,f=!0):s.runs++),s},()=>{f=!0})(c,d)||{},v={id:(0,i.getId)(12),start:t,isNew:!0,count:1,runs:1},y=Object.assign(v,g,p,{device:m},{isStart:f,storage:!0,updated:t},e.data);return(0,a.storageWrite)(c,JSON.stringify(y),2*r,d),y}var l=require("@walkeros/core");function g(e={}){const{cb:t,consent:r,collector:n,storage:s}=e;if(!r)return f((s?d:u)(e),n,t);{const s=function(e,t){let r;const n=(n,s)=>{if((0,l.isDefined)(r)&&r===(null==n?void 0:n.group))return;r=null==n?void 0:n.group;let o=()=>u(e);if(e.consent){const t=((0,l.isArray)(e.consent)?e.consent:[e.consent]).reduce((e,t)=>({...e,[t]:!0}),{});(0,l.getGrantedConsent)(t,s)&&(o=()=>d(e))}return f(o(),n,t)};return n}(e,t),o=((0,l.isArray)(r)?r:[r]).reduce((e,t)=>({...e,[t]:s}),{});n&&n.command("on","consent",o)}}function f(e,t,r){return!1===r?e:(r||(r=m),r(e,t,m))}var m=(e,t)=>{const r={};return e.id&&(r.session=e.id),e.storage&&e.device&&(r.device=e.device),t&&(t.command("user",r),t.command("session",e)),e.isStart&&t&&t.push({name:"session start",data:e}),e},p={},v=async e=>{const{config:t,env:r}=e,{elb:n,command:s}=r,o={...null==t?void 0:t.settings},i={settings:o},a={push:n,group:void 0,command:s};g({...o,collector:a});return{type:"session",config:i,push:n,on:async e=>{"consent"===e&&g({...o,collector:a})}}},y=v;//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/lib/sessionStorage.ts","../src/lib/sessionWindow.ts","../src/lib/sessionStart.ts","../src/types/index.ts"],"sourcesContent":["import type { Source, On, Collector } from '@walkeros/core';\nimport type { Types, Settings } from './types';\nimport { sessionStart } from './lib';\n\n// Export types for external usage\nexport * as SourceSession from './types';\n\n// Export lib functions for direct usage\nexport { sessionStart, sessionStorage, sessionWindow } from './lib';\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from './lib';\n\n/**\n * Session source implementation.\n *\n * This source handles session detection and management.\n */\nexport const sourceSession: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, command } = env;\n\n const settings: Settings = {\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Create minimal collector interface for sessionStart\n const collectorInterface: Partial<Collector.Instance> = {\n push: elb,\n group: undefined,\n command,\n };\n\n // Initialize session using local lib\n sessionStart({\n ...settings,\n collector: collectorInterface as Collector.Instance,\n });\n\n // Handle events pushed from collector (consent, session, ready, run)\n const handleEvent = async (event: On.Types) => {\n if (event === 'consent') {\n // Re-initialize session on consent changes\n sessionStart({\n ...settings,\n collector: collectorInterface as Collector.Instance,\n });\n }\n };\n\n return {\n type: 'session',\n config: fullConfig,\n push: elb,\n on: handleEvent,\n };\n};\n\nexport default sourceSession;\n","import type { Collector } from '@walkeros/core';\nimport type { SessionWindowConfig } from './sessionWindow';\nimport type { StorageType } from '@walkeros/core';\nimport { getId, tryCatch } from '@walkeros/core';\nimport { storageRead, storageWrite } from '@walkeros/web-core';\nimport { sessionWindow } from './sessionWindow';\n\nexport interface SessionStorageConfig extends SessionWindowConfig {\n deviceKey?: string;\n deviceStorage?: StorageType;\n deviceAge?: number;\n sessionKey?: string;\n sessionStorage?: StorageType;\n length?: number; // Minutes after last update to consider session as expired (default: 30)\n pulse?: boolean;\n}\n\nexport function sessionStorage(\n config: SessionStorageConfig = {},\n): Collector.SessionData {\n const now = Date.now();\n const {\n length = 30, // Session length in minutes\n deviceKey = 'elbDeviceId',\n deviceStorage = 'local',\n deviceAge = 30, // Device ID age in days\n sessionKey = 'elbSessionId',\n sessionStorage = 'local',\n pulse = false, // Handle the counting\n } = config;\n const windowSession = sessionWindow(config); // Status based on window only\n let isStart = false;\n\n // Retrieve or create device ID\n const device = tryCatch((key: string, age: number, storage: StorageType) => {\n let id = storageRead(key, storage);\n if (!id) {\n id = getId(8); // Create a new device ID\n storageWrite(key, id, age * 1440, storage); // Write device ID to storage\n }\n return String(id);\n })(deviceKey, deviceAge, deviceStorage);\n\n // Retrieve or initialize session data\n const existingSession: Collector.SessionData =\n tryCatch(\n (key: string, storage?: StorageType) => {\n const session = JSON.parse(String(storageRead(key, storage)));\n\n // Only update session if it's not a pulse check\n if (pulse) return session;\n\n // Mark session as not new by default\n session.isNew = false;\n\n // Handle new marketing entry\n if (windowSession.marketing) {\n Object.assign(session, windowSession); // Overwrite existing session with marketing data\n isStart = true; // This is a session start\n }\n\n // Check if session is still active\n if (isStart || session.updated + length * 60000 < now) {\n // Session has expired\n delete session.id; // Unset session ID\n delete session.referrer; // Unset referrer\n session.start = now; // Set new session start\n session.count++; // Increase session count\n session.runs = 1; // Reset runs\n isStart = true; // It's a new session\n } else {\n // Session is still active\n session.runs++; // Increase number of runs\n }\n\n return session;\n },\n () => {\n // No existing session or something went wrong\n isStart = true; // Start a new session\n },\n )(sessionKey, sessionStorage) || {};\n\n // Default session data\n const defaultSession: Partial<Collector.SessionData> = {\n id: getId(12),\n start: now,\n isNew: true,\n count: 1,\n runs: 1,\n };\n\n // Merge session data\n const session = Object.assign(\n defaultSession, // Default session values\n windowSession, // Basic session data based on window\n existingSession, // (Updated) existing session\n { device }, // Device ID\n { isStart, storage: true, updated: now }, // Status of the session\n config.data, // Given data has the highest priority\n );\n\n // Write (updated) session to storage\n storageWrite(sessionKey, JSON.stringify(session), length * 2, sessionStorage);\n\n return session;\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport {\n getId,\n getMarketingParameters,\n type MarketingParameters,\n} from '@walkeros/core';\n\nexport interface SessionWindowConfig {\n data?: WalkerOS.Properties;\n domains?: string[];\n isStart?: boolean;\n parameters?: MarketingParameters;\n referrer?: string;\n url?: string;\n}\n\nexport function sessionWindow(\n config: SessionWindowConfig = {},\n): Collector.SessionData {\n let isStart = config.isStart || false;\n const known = { isStart, storage: false };\n\n // If session has explicitly started, return known\n if (config.isStart === false) return known;\n\n // Entry type\n if (!isStart) {\n // Only focus on linked or direct navigation types\n // and ignore reloads and all others\n const [perf] = performance.getEntriesByType(\n 'navigation',\n ) as PerformanceNavigationTiming[];\n if (perf.type !== 'navigate') return known;\n }\n\n const url = new URL(config.url || window.location.href);\n const ref = config.referrer || document.referrer;\n const referrer = ref && new URL(ref).hostname;\n\n // Marketing\n const marketing = getMarketingParameters(url, config.parameters);\n if (Object.keys(marketing).length) {\n // Check for marketing parameters like UTM and add existing\n if (!marketing.marketing)\n // Flag as a marketing session without overwriting\n marketing.marketing = true;\n\n isStart = true;\n }\n\n // Referrer\n if (!isStart) {\n // Small chance of multiple unintended events for same users\n // https://en.wikipedia.org/wiki/HTTP_referer#Referrer_hiding\n // Use domains: [''] to disable direct or hidden referrer\n\n const domains = config.domains || [];\n domains.push(url.hostname);\n isStart = !domains.includes(referrer);\n }\n\n return isStart\n ? // It's a session start, moin\n Object.assign(\n {\n isStart,\n storage: false,\n start: Date.now(),\n id: getId(12),\n referrer,\n },\n marketing,\n config.data,\n )\n : // No session start\n known;\n}\n","import type { Collector, WalkerOS, On } from '@walkeros/core';\nimport type { SessionStorageConfig } from './sessionStorage';\nimport { sessionStorage } from './sessionStorage';\nimport { sessionWindow } from './sessionWindow';\nimport { getGrantedConsent, isArray, isDefined } from '@walkeros/core';\n\nexport interface SessionConfig extends SessionStorageConfig {\n consent?: string | string[];\n storage?: boolean;\n cb?: SessionCallback | false;\n collector?: Collector.Instance;\n}\n\nexport type SessionFunction = typeof sessionStorage | typeof sessionWindow;\nexport type SessionCallback = (\n session: Collector.SessionData,\n collector: Collector.Instance | undefined,\n defaultCb: SessionCallback,\n) => void;\n\nexport function sessionStart(\n config: SessionConfig = {},\n): Collector.SessionData | void {\n const { cb, consent, collector, storage } = config;\n const sessionFn: SessionFunction = storage ? sessionStorage : sessionWindow;\n\n // Consent\n if (consent) {\n const consentHandler = onConsentFn(config, cb);\n\n const consentConfig = (\n isArray(consent) ? consent : [consent]\n ).reduce<On.ConsentConfig>(\n (acc, key) => ({ ...acc, [key]: consentHandler }),\n {},\n );\n // Register consent handlers with the collector\n if (collector) {\n collector.command('on', 'consent', consentConfig);\n }\n // No fallback - session source always provides collector\n } else {\n // just do it\n return callFuncAndCb(sessionFn(config), collector, cb);\n }\n}\n\nfunction callFuncAndCb(\n session: Collector.SessionData,\n collector?: Collector.Instance,\n cb?: SessionCallback | false,\n) {\n if (cb === false) return session; // Callback is disabled\n if (!cb) cb = defaultCb; // Default callback if none is provided\n return cb(session, collector, defaultCb);\n}\n\nfunction onConsentFn(config: SessionConfig, cb?: SessionCallback | false) {\n // Track the last processed group to prevent duplicate processing\n let lastProcessedGroup: string | undefined;\n\n const func = (collector: Collector.Instance, consent: WalkerOS.Consent) => {\n // Skip if we've already processed this group\n if (\n isDefined(lastProcessedGroup) &&\n lastProcessedGroup === collector?.group\n )\n return;\n\n // Remember this group has been processed\n lastProcessedGroup = collector?.group;\n\n let sessionFn: SessionFunction = () => sessionWindow(config); // Window by default\n\n if (config.consent) {\n const consentKeys = (\n isArray(config.consent) ? config.consent : [config.consent]\n ).reduce<WalkerOS.Consent>((acc, key) => ({ ...acc, [key]: true }), {});\n\n if (getGrantedConsent(consentKeys, consent))\n // Use storage if consent is granted\n sessionFn = () => sessionStorage(config);\n }\n\n return callFuncAndCb(sessionFn(), collector, cb);\n };\n\n return func;\n}\n\nconst defaultCb: SessionCallback = (\n session,\n collector,\n): Collector.SessionData => {\n const user: WalkerOS.User = {};\n\n // User.session is the session ID\n if (session.id) user.session = session.id;\n\n // Set device ID only in storage mode\n if (session.storage && session.device) user.device = session.device;\n\n // Set user IDs\n if (collector) {\n collector.command('user', user);\n }\n // No fallback - session source always provides collector\n\n if (session.isStart) {\n // Convert session start to an event object\n if (collector) {\n collector.push({\n name: 'session start',\n data: session,\n });\n }\n // No fallback - session source always provides collector\n }\n\n return session;\n};\n","import type { Source, Elb } from '@walkeros/core';\nimport type { SessionConfig, SessionCallback } from '../lib';\n\n// Settings: configuration for session source\nexport interface Settings extends SessionConfig {\n // All settings inherited from SessionConfig:\n // - consent?: string | string[]\n // - storage?: boolean\n // - cb?: SessionCallback | false\n // - pulse?: boolean\n // - sessionStorage?: 'local' | 'session'\n // - deviceStorage?: 'local' | 'session'\n // - sessionKey?: string\n // - deviceKey?: string\n // - length?: number (session timeout in minutes)\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\n// Re-export session types from lib\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from '../lib';\n"],"mappings":"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","names":["import_core","sessionStorage","session","import_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/lib/sessionStorage.ts","../src/lib/sessionWindow.ts","../src/lib/sessionStart.ts","../src/types/index.ts"],"sourcesContent":["import type { Source, On, Collector } from '@walkeros/core';\nimport type { Types, Settings } from './types';\nimport { sessionStart } from './lib';\n\n// Export types for external usage\nexport * as SourceSession from './types';\n\n// Export lib functions for direct usage\nexport { sessionStart, sessionStorage, sessionWindow } from './lib';\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from './lib';\n\n/**\n * Session source implementation.\n *\n * This source handles session detection and management.\n */\nexport const sourceSession: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, command } = env;\n\n const settings: Settings = {\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Create minimal collector interface for sessionStart\n const collectorInterface: Partial<Collector.Instance> = {\n push: elb,\n group: undefined,\n command,\n };\n\n // Initialize session using local lib\n sessionStart({\n ...settings,\n collector: collectorInterface as Collector.Instance,\n });\n\n // Handle events pushed from collector (consent, session, ready, run)\n const handleEvent = async (event: On.Types) => {\n if (event === 'consent') {\n // Re-initialize session on consent changes\n sessionStart({\n ...settings,\n collector: collectorInterface as Collector.Instance,\n });\n }\n };\n\n return {\n type: 'session',\n config: fullConfig,\n push: elb,\n on: handleEvent,\n };\n};\n\nexport default sourceSession;\n","import type { Collector } from '@walkeros/core';\nimport type { SessionWindowConfig } from './sessionWindow';\nimport type { StorageType } from '@walkeros/core';\nimport { getId, tryCatch } from '@walkeros/core';\nimport { storageRead, storageWrite } from '@walkeros/web-core';\nimport { sessionWindow } from './sessionWindow';\n\nexport interface SessionStorageConfig extends SessionWindowConfig {\n deviceKey?: string;\n deviceStorage?: StorageType;\n deviceAge?: number;\n sessionKey?: string;\n sessionStorage?: StorageType;\n length?: number; // Minutes after last update to consider session as expired (default: 30)\n pulse?: boolean;\n}\n\nexport function sessionStorage(\n config: SessionStorageConfig = {},\n): Collector.SessionData {\n const now = Date.now();\n const {\n length = 30, // Session length in minutes\n deviceKey = 'elbDeviceId',\n deviceStorage = 'local',\n deviceAge = 30, // Device ID age in days\n sessionKey = 'elbSessionId',\n sessionStorage = 'local',\n pulse = false, // Handle the counting\n } = config;\n const windowSession = sessionWindow(config); // Status based on window only\n let isStart = false;\n\n // Retrieve or create device ID\n const device = tryCatch((key: string, age: number, storage: StorageType) => {\n let id = storageRead(key, storage);\n if (!id) {\n id = getId(8); // Create a new device ID\n storageWrite(key, id, age * 1440, storage); // Write device ID to storage\n }\n return String(id);\n })(deviceKey, deviceAge, deviceStorage);\n\n // Retrieve or initialize session data\n const existingSession: Collector.SessionData =\n tryCatch(\n (key: string, storage?: StorageType) => {\n const session = JSON.parse(String(storageRead(key, storage)));\n\n // Only update session if it's not a pulse check\n if (pulse) return session;\n\n // Mark session as not new by default\n session.isNew = false;\n\n // Handle new marketing entry\n if (windowSession.marketing) {\n Object.assign(session, windowSession); // Overwrite existing session with marketing data\n isStart = true; // This is a session start\n }\n\n // Check if session is still active\n if (isStart || session.updated + length * 60000 < now) {\n // Session has expired\n delete session.id; // Unset session ID\n delete session.referrer; // Unset referrer\n session.start = now; // Set new session start\n session.count++; // Increase session count\n session.runs = 1; // Reset runs\n isStart = true; // It's a new session\n } else {\n // Session is still active\n session.runs++; // Increase number of runs\n }\n\n return session;\n },\n () => {\n // No existing session or something went wrong\n isStart = true; // Start a new session\n },\n )(sessionKey, sessionStorage) || {};\n\n // Default session data\n const defaultSession: Partial<Collector.SessionData> = {\n id: getId(12),\n start: now,\n isNew: true,\n count: 1,\n runs: 1,\n };\n\n // Merge session data\n const session = Object.assign(\n defaultSession, // Default session values\n windowSession, // Basic session data based on window\n existingSession, // (Updated) existing session\n { device }, // Device ID\n { isStart, storage: true, updated: now }, // Status of the session\n config.data, // Given data has the highest priority\n );\n\n // Write (updated) session to storage\n storageWrite(sessionKey, JSON.stringify(session), length * 2, sessionStorage);\n\n return session;\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport {\n getId,\n getMarketingParameters,\n type MarketingParameters,\n} from '@walkeros/core';\n\nexport interface SessionWindowConfig {\n data?: WalkerOS.Properties;\n domains?: string[];\n isStart?: boolean;\n parameters?: MarketingParameters;\n referrer?: string;\n url?: string;\n}\n\nexport function sessionWindow(\n config: SessionWindowConfig = {},\n): Collector.SessionData {\n let isStart = config.isStart || false;\n const known = { isStart, storage: false };\n\n // If session has explicitly started, return known\n if (config.isStart === false) return known;\n\n // Entry type\n if (!isStart) {\n // Only focus on linked or direct navigation types\n // and ignore reloads and all others\n const [perf] = performance.getEntriesByType(\n 'navigation',\n ) as PerformanceNavigationTiming[];\n if (perf.type !== 'navigate') return known;\n }\n\n const url = new URL(config.url || window.location.href);\n const ref = config.referrer || document.referrer;\n const referrer = ref && new URL(ref).hostname;\n\n // Marketing\n const marketing = getMarketingParameters(url, config.parameters);\n if (Object.keys(marketing).length) {\n // Check for marketing parameters like UTM and add existing\n if (!marketing.marketing)\n // Flag as a marketing session without overwriting\n marketing.marketing = true;\n\n isStart = true;\n }\n\n // Referrer\n if (!isStart) {\n // Small chance of multiple unintended events for same users\n // https://en.wikipedia.org/wiki/HTTP_referer#Referrer_hiding\n // Use domains: [''] to disable direct or hidden referrer\n\n const domains = config.domains || [];\n domains.push(url.hostname);\n isStart = !domains.includes(referrer);\n }\n\n return isStart\n ? // It's a session start, moin\n Object.assign(\n {\n isStart,\n storage: false,\n start: Date.now(),\n id: getId(12),\n referrer,\n },\n marketing,\n config.data,\n )\n : // No session start\n known;\n}\n","import type { Collector, WalkerOS, On } from '@walkeros/core';\nimport type { SessionStorageConfig } from './sessionStorage';\nimport { sessionStorage } from './sessionStorage';\nimport { sessionWindow } from './sessionWindow';\nimport { getGrantedConsent, isArray, isDefined } from '@walkeros/core';\n\nexport interface SessionConfig extends SessionStorageConfig {\n consent?: string | string[];\n storage?: boolean;\n cb?: SessionCallback | false;\n collector?: Collector.Instance;\n}\n\nexport type SessionFunction = typeof sessionStorage | typeof sessionWindow;\nexport type SessionCallback = (\n session: Collector.SessionData,\n collector: Collector.Instance | undefined,\n defaultCb: SessionCallback,\n) => void;\n\nexport function sessionStart(\n config: SessionConfig = {},\n): Collector.SessionData | void {\n const { cb, consent, collector, storage } = config;\n const sessionFn: SessionFunction = storage ? sessionStorage : sessionWindow;\n\n // Consent\n if (consent) {\n const consentHandler = onConsentFn(config, cb);\n\n const consentConfig = (\n isArray(consent) ? consent : [consent]\n ).reduce<On.ConsentConfig>(\n (acc, key) => ({ ...acc, [key]: consentHandler }),\n {},\n );\n // Register consent handlers with the collector\n if (collector) {\n collector.command('on', 'consent', consentConfig);\n }\n // No fallback - session source always provides collector\n } else {\n // just do it\n return callFuncAndCb(sessionFn(config), collector, cb);\n }\n}\n\nfunction callFuncAndCb(\n session: Collector.SessionData,\n collector?: Collector.Instance,\n cb?: SessionCallback | false,\n) {\n if (cb === false) return session; // Callback is disabled\n if (!cb) cb = defaultCb; // Default callback if none is provided\n return cb(session, collector, defaultCb);\n}\n\nfunction onConsentFn(config: SessionConfig, cb?: SessionCallback | false) {\n // Track the last processed group to prevent duplicate processing\n let lastProcessedGroup: string | undefined;\n\n const func = (collector: Collector.Instance, consent: WalkerOS.Consent) => {\n // Skip if we've already processed this group\n if (\n isDefined(lastProcessedGroup) &&\n lastProcessedGroup === collector?.group\n )\n return;\n\n // Remember this group has been processed\n lastProcessedGroup = collector?.group;\n\n let sessionFn: SessionFunction = () => sessionWindow(config); // Window by default\n\n if (config.consent) {\n const consentKeys = (\n isArray(config.consent) ? config.consent : [config.consent]\n ).reduce<WalkerOS.Consent>((acc, key) => ({ ...acc, [key]: true }), {});\n\n if (getGrantedConsent(consentKeys, consent))\n // Use storage if consent is granted\n sessionFn = () => sessionStorage(config);\n }\n\n return callFuncAndCb(sessionFn(), collector, cb);\n };\n\n return func;\n}\n\nconst defaultCb: SessionCallback = (\n session,\n collector,\n): Collector.SessionData => {\n const user: WalkerOS.User = {};\n\n // User.session is the session ID\n if (session.id) user.session = session.id;\n\n // Set device ID only in storage mode\n if (session.storage && session.device) user.device = session.device;\n\n // Set user IDs and broadcast session data\n if (collector) {\n collector.command('user', user);\n collector.command('session', session);\n }\n // No fallback - session source always provides collector\n\n if (session.isStart) {\n // Convert session start to an event object\n if (collector) {\n collector.push({\n name: 'session start',\n data: session,\n });\n }\n // No fallback - session source always provides collector\n }\n\n return session;\n};\n","import type { Source, Elb } from '@walkeros/core';\nimport type { SessionConfig, SessionCallback } from '../lib';\n\n// Settings: configuration for session source\nexport interface Settings extends SessionConfig {\n // All settings inherited from SessionConfig:\n // - consent?: string | string[]\n // - storage?: boolean\n // - cb?: SessionCallback | false\n // - pulse?: boolean\n // - sessionStorage?: 'local' | 'session'\n // - deviceStorage?: 'local' | 'session'\n // - sessionKey?: string\n // - deviceKey?: string\n // - length?: number (session timeout in minutes)\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\n// Re-export session types from lib\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from '../lib';\n"],"mappings":"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","names":["import_core","sessionStorage","session","import_core"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,233 +1 @@
|
|
|
1
|
-
import "
|
|
2
|
-
|
|
3
|
-
// src/lib/sessionStorage.ts
|
|
4
|
-
import { getId as getId2, tryCatch } from "@walkeros/core";
|
|
5
|
-
import { storageRead, storageWrite } from "@walkeros/web-core";
|
|
6
|
-
|
|
7
|
-
// src/lib/sessionWindow.ts
|
|
8
|
-
import {
|
|
9
|
-
getId,
|
|
10
|
-
getMarketingParameters
|
|
11
|
-
} from "@walkeros/core";
|
|
12
|
-
function sessionWindow(config = {}) {
|
|
13
|
-
let isStart = config.isStart || false;
|
|
14
|
-
const known = { isStart, storage: false };
|
|
15
|
-
if (config.isStart === false) return known;
|
|
16
|
-
if (!isStart) {
|
|
17
|
-
const [perf] = performance.getEntriesByType(
|
|
18
|
-
"navigation"
|
|
19
|
-
);
|
|
20
|
-
if (perf.type !== "navigate") return known;
|
|
21
|
-
}
|
|
22
|
-
const url = new URL(config.url || window.location.href);
|
|
23
|
-
const ref = config.referrer || document.referrer;
|
|
24
|
-
const referrer = ref && new URL(ref).hostname;
|
|
25
|
-
const marketing = getMarketingParameters(url, config.parameters);
|
|
26
|
-
if (Object.keys(marketing).length) {
|
|
27
|
-
if (!marketing.marketing)
|
|
28
|
-
marketing.marketing = true;
|
|
29
|
-
isStart = true;
|
|
30
|
-
}
|
|
31
|
-
if (!isStart) {
|
|
32
|
-
const domains = config.domains || [];
|
|
33
|
-
domains.push(url.hostname);
|
|
34
|
-
isStart = !domains.includes(referrer);
|
|
35
|
-
}
|
|
36
|
-
return isStart ? (
|
|
37
|
-
// It's a session start, moin
|
|
38
|
-
Object.assign(
|
|
39
|
-
{
|
|
40
|
-
isStart,
|
|
41
|
-
storage: false,
|
|
42
|
-
start: Date.now(),
|
|
43
|
-
id: getId(12),
|
|
44
|
-
referrer
|
|
45
|
-
},
|
|
46
|
-
marketing,
|
|
47
|
-
config.data
|
|
48
|
-
)
|
|
49
|
-
) : (
|
|
50
|
-
// No session start
|
|
51
|
-
known
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// src/lib/sessionStorage.ts
|
|
56
|
-
function sessionStorage(config = {}) {
|
|
57
|
-
const now = Date.now();
|
|
58
|
-
const {
|
|
59
|
-
length = 30,
|
|
60
|
-
// Session length in minutes
|
|
61
|
-
deviceKey = "elbDeviceId",
|
|
62
|
-
deviceStorage = "local",
|
|
63
|
-
deviceAge = 30,
|
|
64
|
-
// Device ID age in days
|
|
65
|
-
sessionKey = "elbSessionId",
|
|
66
|
-
sessionStorage: sessionStorage2 = "local",
|
|
67
|
-
pulse = false
|
|
68
|
-
// Handle the counting
|
|
69
|
-
} = config;
|
|
70
|
-
const windowSession = sessionWindow(config);
|
|
71
|
-
let isStart = false;
|
|
72
|
-
const device = tryCatch((key, age, storage) => {
|
|
73
|
-
let id = storageRead(key, storage);
|
|
74
|
-
if (!id) {
|
|
75
|
-
id = getId2(8);
|
|
76
|
-
storageWrite(key, id, age * 1440, storage);
|
|
77
|
-
}
|
|
78
|
-
return String(id);
|
|
79
|
-
})(deviceKey, deviceAge, deviceStorage);
|
|
80
|
-
const existingSession = tryCatch(
|
|
81
|
-
(key, storage) => {
|
|
82
|
-
const session2 = JSON.parse(String(storageRead(key, storage)));
|
|
83
|
-
if (pulse) return session2;
|
|
84
|
-
session2.isNew = false;
|
|
85
|
-
if (windowSession.marketing) {
|
|
86
|
-
Object.assign(session2, windowSession);
|
|
87
|
-
isStart = true;
|
|
88
|
-
}
|
|
89
|
-
if (isStart || session2.updated + length * 6e4 < now) {
|
|
90
|
-
delete session2.id;
|
|
91
|
-
delete session2.referrer;
|
|
92
|
-
session2.start = now;
|
|
93
|
-
session2.count++;
|
|
94
|
-
session2.runs = 1;
|
|
95
|
-
isStart = true;
|
|
96
|
-
} else {
|
|
97
|
-
session2.runs++;
|
|
98
|
-
}
|
|
99
|
-
return session2;
|
|
100
|
-
},
|
|
101
|
-
() => {
|
|
102
|
-
isStart = true;
|
|
103
|
-
}
|
|
104
|
-
)(sessionKey, sessionStorage2) || {};
|
|
105
|
-
const defaultSession = {
|
|
106
|
-
id: getId2(12),
|
|
107
|
-
start: now,
|
|
108
|
-
isNew: true,
|
|
109
|
-
count: 1,
|
|
110
|
-
runs: 1
|
|
111
|
-
};
|
|
112
|
-
const session = Object.assign(
|
|
113
|
-
defaultSession,
|
|
114
|
-
// Default session values
|
|
115
|
-
windowSession,
|
|
116
|
-
// Basic session data based on window
|
|
117
|
-
existingSession,
|
|
118
|
-
// (Updated) existing session
|
|
119
|
-
{ device },
|
|
120
|
-
// Device ID
|
|
121
|
-
{ isStart, storage: true, updated: now },
|
|
122
|
-
// Status of the session
|
|
123
|
-
config.data
|
|
124
|
-
// Given data has the highest priority
|
|
125
|
-
);
|
|
126
|
-
storageWrite(sessionKey, JSON.stringify(session), length * 2, sessionStorage2);
|
|
127
|
-
return session;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// src/lib/sessionStart.ts
|
|
131
|
-
import { getGrantedConsent, isArray, isDefined } from "@walkeros/core";
|
|
132
|
-
function sessionStart(config = {}) {
|
|
133
|
-
const { cb, consent, collector, storage } = config;
|
|
134
|
-
const sessionFn = storage ? sessionStorage : sessionWindow;
|
|
135
|
-
if (consent) {
|
|
136
|
-
const consentHandler = onConsentFn(config, cb);
|
|
137
|
-
const consentConfig = (isArray(consent) ? consent : [consent]).reduce(
|
|
138
|
-
(acc, key) => ({ ...acc, [key]: consentHandler }),
|
|
139
|
-
{}
|
|
140
|
-
);
|
|
141
|
-
if (collector) {
|
|
142
|
-
collector.command("on", "consent", consentConfig);
|
|
143
|
-
}
|
|
144
|
-
} else {
|
|
145
|
-
return callFuncAndCb(sessionFn(config), collector, cb);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
function callFuncAndCb(session, collector, cb) {
|
|
149
|
-
if (cb === false) return session;
|
|
150
|
-
if (!cb) cb = defaultCb;
|
|
151
|
-
return cb(session, collector, defaultCb);
|
|
152
|
-
}
|
|
153
|
-
function onConsentFn(config, cb) {
|
|
154
|
-
let lastProcessedGroup;
|
|
155
|
-
const func = (collector, consent) => {
|
|
156
|
-
if (isDefined(lastProcessedGroup) && lastProcessedGroup === (collector == null ? void 0 : collector.group))
|
|
157
|
-
return;
|
|
158
|
-
lastProcessedGroup = collector == null ? void 0 : collector.group;
|
|
159
|
-
let sessionFn = () => sessionWindow(config);
|
|
160
|
-
if (config.consent) {
|
|
161
|
-
const consentKeys = (isArray(config.consent) ? config.consent : [config.consent]).reduce((acc, key) => ({ ...acc, [key]: true }), {});
|
|
162
|
-
if (getGrantedConsent(consentKeys, consent))
|
|
163
|
-
sessionFn = () => sessionStorage(config);
|
|
164
|
-
}
|
|
165
|
-
return callFuncAndCb(sessionFn(), collector, cb);
|
|
166
|
-
};
|
|
167
|
-
return func;
|
|
168
|
-
}
|
|
169
|
-
var defaultCb = (session, collector) => {
|
|
170
|
-
const user = {};
|
|
171
|
-
if (session.id) user.session = session.id;
|
|
172
|
-
if (session.storage && session.device) user.device = session.device;
|
|
173
|
-
if (collector) {
|
|
174
|
-
collector.command("user", user);
|
|
175
|
-
}
|
|
176
|
-
if (session.isStart) {
|
|
177
|
-
if (collector) {
|
|
178
|
-
collector.push({
|
|
179
|
-
name: "session start",
|
|
180
|
-
data: session
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return session;
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
// src/types/index.ts
|
|
188
|
-
var types_exports = {};
|
|
189
|
-
|
|
190
|
-
// src/index.ts
|
|
191
|
-
var sourceSession = async (context) => {
|
|
192
|
-
const { config, env } = context;
|
|
193
|
-
const { elb, command } = env;
|
|
194
|
-
const settings = {
|
|
195
|
-
...config == null ? void 0 : config.settings
|
|
196
|
-
};
|
|
197
|
-
const fullConfig = {
|
|
198
|
-
settings
|
|
199
|
-
};
|
|
200
|
-
const collectorInterface = {
|
|
201
|
-
push: elb,
|
|
202
|
-
group: void 0,
|
|
203
|
-
command
|
|
204
|
-
};
|
|
205
|
-
sessionStart({
|
|
206
|
-
...settings,
|
|
207
|
-
collector: collectorInterface
|
|
208
|
-
});
|
|
209
|
-
const handleEvent = async (event) => {
|
|
210
|
-
if (event === "consent") {
|
|
211
|
-
sessionStart({
|
|
212
|
-
...settings,
|
|
213
|
-
collector: collectorInterface
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
return {
|
|
218
|
-
type: "session",
|
|
219
|
-
config: fullConfig,
|
|
220
|
-
push: elb,
|
|
221
|
-
on: handleEvent
|
|
222
|
-
};
|
|
223
|
-
};
|
|
224
|
-
var index_default = sourceSession;
|
|
225
|
-
export {
|
|
226
|
-
types_exports as SourceSession,
|
|
227
|
-
index_default as default,
|
|
228
|
-
sessionStart,
|
|
229
|
-
sessionStorage,
|
|
230
|
-
sessionWindow,
|
|
231
|
-
sourceSession
|
|
232
|
-
};
|
|
233
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
import{getId as e,tryCatch as t}from"@walkeros/core";import{storageRead as n,storageWrite as r}from"@walkeros/web-core";import{getId as s,getMarketingParameters as o}from"@walkeros/core";function i(e={}){let t=e.isStart||!1;const n={isStart:t,storage:!1};if(!1===e.isStart)return n;if(!t){const[e]=performance.getEntriesByType("navigation");if("navigate"!==e.type)return n}const r=new URL(e.url||window.location.href),i=e.referrer||document.referrer,c=i&&new URL(i).hostname,a=o(r,e.parameters);if(Object.keys(a).length&&(a.marketing||(a.marketing=!0),t=!0),!t){const n=e.domains||[];n.push(r.hostname),t=!n.includes(c)}return t?Object.assign({isStart:t,storage:!1,start:Date.now(),id:s(12),referrer:c},a,e.data):n}function c(s={}){const o=Date.now(),{length:c=30,deviceKey:a="elbDeviceId",deviceStorage:u="local",deviceAge:d=30,sessionKey:l="elbSessionId",sessionStorage:g="local",pulse:m=!1}=s,f=i(s);let p=!1;const v=t((t,s,o)=>{let i=n(t,o);return i||(i=e(8),r(t,i,1440*s,o)),String(i)})(a,d,u),S=t((e,t)=>{const r=JSON.parse(String(n(e,t)));return m||(r.isNew=!1,f.marketing&&(Object.assign(r,f),p=!0),p||r.updated+6e4*c<o?(delete r.id,delete r.referrer,r.start=o,r.count++,r.runs=1,p=!0):r.runs++),r},()=>{p=!0})(l,g)||{},w={id:e(12),start:o,isNew:!0,count:1,runs:1},y=Object.assign(w,f,S,{device:v},{isStart:p,storage:!0,updated:o},s.data);return r(l,JSON.stringify(y),2*c,g),y}import{getGrantedConsent as a,isArray as u,isDefined as d}from"@walkeros/core";function l(e={}){const{cb:t,consent:n,collector:r,storage:s}=e;if(!n)return g((s?c:i)(e),r,t);{const s=function(e,t){let n;const r=(r,s)=>{if(d(n)&&n===(null==r?void 0:r.group))return;n=null==r?void 0:r.group;let o=()=>i(e);if(e.consent){const t=(u(e.consent)?e.consent:[e.consent]).reduce((e,t)=>({...e,[t]:!0}),{});a(t,s)&&(o=()=>c(e))}return g(o(),r,t)};return r}(e,t),o=(u(n)?n:[n]).reduce((e,t)=>({...e,[t]:s}),{});r&&r.command("on","consent",o)}}function g(e,t,n){return!1===n?e:(n||(n=m),n(e,t,m))}var m=(e,t)=>{const n={};return e.id&&(n.session=e.id),e.storage&&e.device&&(n.device=e.device),t&&(t.command("user",n),t.command("session",e)),e.isStart&&t&&t.push({name:"session start",data:e}),e},f={},p=async e=>{const{config:t,env:n}=e,{elb:r,command:s}=n,o={...null==t?void 0:t.settings},i={settings:o},c={push:r,group:void 0,command:s};l({...o,collector:c});return{type:"session",config:i,push:r,on:async e=>{"consent"===e&&l({...o,collector:c})}}},v=p;export{f as SourceSession,v as default,l as sessionStart,c as sessionStorage,i as sessionWindow,p as sourceSession};//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/sessionStorage.ts","../src/lib/sessionWindow.ts","../src/lib/sessionStart.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Collector } from '@walkeros/core';\nimport type { SessionWindowConfig } from './sessionWindow';\nimport type { StorageType } from '@walkeros/core';\nimport { getId, tryCatch } from '@walkeros/core';\nimport { storageRead, storageWrite } from '@walkeros/web-core';\nimport { sessionWindow } from './sessionWindow';\n\nexport interface SessionStorageConfig extends SessionWindowConfig {\n deviceKey?: string;\n deviceStorage?: StorageType;\n deviceAge?: number;\n sessionKey?: string;\n sessionStorage?: StorageType;\n length?: number; // Minutes after last update to consider session as expired (default: 30)\n pulse?: boolean;\n}\n\nexport function sessionStorage(\n config: SessionStorageConfig = {},\n): Collector.SessionData {\n const now = Date.now();\n const {\n length = 30, // Session length in minutes\n deviceKey = 'elbDeviceId',\n deviceStorage = 'local',\n deviceAge = 30, // Device ID age in days\n sessionKey = 'elbSessionId',\n sessionStorage = 'local',\n pulse = false, // Handle the counting\n } = config;\n const windowSession = sessionWindow(config); // Status based on window only\n let isStart = false;\n\n // Retrieve or create device ID\n const device = tryCatch((key: string, age: number, storage: StorageType) => {\n let id = storageRead(key, storage);\n if (!id) {\n id = getId(8); // Create a new device ID\n storageWrite(key, id, age * 1440, storage); // Write device ID to storage\n }\n return String(id);\n })(deviceKey, deviceAge, deviceStorage);\n\n // Retrieve or initialize session data\n const existingSession: Collector.SessionData =\n tryCatch(\n (key: string, storage?: StorageType) => {\n const session = JSON.parse(String(storageRead(key, storage)));\n\n // Only update session if it's not a pulse check\n if (pulse) return session;\n\n // Mark session as not new by default\n session.isNew = false;\n\n // Handle new marketing entry\n if (windowSession.marketing) {\n Object.assign(session, windowSession); // Overwrite existing session with marketing data\n isStart = true; // This is a session start\n }\n\n // Check if session is still active\n if (isStart || session.updated + length * 60000 < now) {\n // Session has expired\n delete session.id; // Unset session ID\n delete session.referrer; // Unset referrer\n session.start = now; // Set new session start\n session.count++; // Increase session count\n session.runs = 1; // Reset runs\n isStart = true; // It's a new session\n } else {\n // Session is still active\n session.runs++; // Increase number of runs\n }\n\n return session;\n },\n () => {\n // No existing session or something went wrong\n isStart = true; // Start a new session\n },\n )(sessionKey, sessionStorage) || {};\n\n // Default session data\n const defaultSession: Partial<Collector.SessionData> = {\n id: getId(12),\n start: now,\n isNew: true,\n count: 1,\n runs: 1,\n };\n\n // Merge session data\n const session = Object.assign(\n defaultSession, // Default session values\n windowSession, // Basic session data based on window\n existingSession, // (Updated) existing session\n { device }, // Device ID\n { isStart, storage: true, updated: now }, // Status of the session\n config.data, // Given data has the highest priority\n );\n\n // Write (updated) session to storage\n storageWrite(sessionKey, JSON.stringify(session), length * 2, sessionStorage);\n\n return session;\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport {\n getId,\n getMarketingParameters,\n type MarketingParameters,\n} from '@walkeros/core';\n\nexport interface SessionWindowConfig {\n data?: WalkerOS.Properties;\n domains?: string[];\n isStart?: boolean;\n parameters?: MarketingParameters;\n referrer?: string;\n url?: string;\n}\n\nexport function sessionWindow(\n config: SessionWindowConfig = {},\n): Collector.SessionData {\n let isStart = config.isStart || false;\n const known = { isStart, storage: false };\n\n // If session has explicitly started, return known\n if (config.isStart === false) return known;\n\n // Entry type\n if (!isStart) {\n // Only focus on linked or direct navigation types\n // and ignore reloads and all others\n const [perf] = performance.getEntriesByType(\n 'navigation',\n ) as PerformanceNavigationTiming[];\n if (perf.type !== 'navigate') return known;\n }\n\n const url = new URL(config.url || window.location.href);\n const ref = config.referrer || document.referrer;\n const referrer = ref && new URL(ref).hostname;\n\n // Marketing\n const marketing = getMarketingParameters(url, config.parameters);\n if (Object.keys(marketing).length) {\n // Check for marketing parameters like UTM and add existing\n if (!marketing.marketing)\n // Flag as a marketing session without overwriting\n marketing.marketing = true;\n\n isStart = true;\n }\n\n // Referrer\n if (!isStart) {\n // Small chance of multiple unintended events for same users\n // https://en.wikipedia.org/wiki/HTTP_referer#Referrer_hiding\n // Use domains: [''] to disable direct or hidden referrer\n\n const domains = config.domains || [];\n domains.push(url.hostname);\n isStart = !domains.includes(referrer);\n }\n\n return isStart\n ? // It's a session start, moin\n Object.assign(\n {\n isStart,\n storage: false,\n start: Date.now(),\n id: getId(12),\n referrer,\n },\n marketing,\n config.data,\n )\n : // No session start\n known;\n}\n","import type { Collector, WalkerOS, On } from '@walkeros/core';\nimport type { SessionStorageConfig } from './sessionStorage';\nimport { sessionStorage } from './sessionStorage';\nimport { sessionWindow } from './sessionWindow';\nimport { getGrantedConsent, isArray, isDefined } from '@walkeros/core';\n\nexport interface SessionConfig extends SessionStorageConfig {\n consent?: string | string[];\n storage?: boolean;\n cb?: SessionCallback | false;\n collector?: Collector.Instance;\n}\n\nexport type SessionFunction = typeof sessionStorage | typeof sessionWindow;\nexport type SessionCallback = (\n session: Collector.SessionData,\n collector: Collector.Instance | undefined,\n defaultCb: SessionCallback,\n) => void;\n\nexport function sessionStart(\n config: SessionConfig = {},\n): Collector.SessionData | void {\n const { cb, consent, collector, storage } = config;\n const sessionFn: SessionFunction = storage ? sessionStorage : sessionWindow;\n\n // Consent\n if (consent) {\n const consentHandler = onConsentFn(config, cb);\n\n const consentConfig = (\n isArray(consent) ? consent : [consent]\n ).reduce<On.ConsentConfig>(\n (acc, key) => ({ ...acc, [key]: consentHandler }),\n {},\n );\n // Register consent handlers with the collector\n if (collector) {\n collector.command('on', 'consent', consentConfig);\n }\n // No fallback - session source always provides collector\n } else {\n // just do it\n return callFuncAndCb(sessionFn(config), collector, cb);\n }\n}\n\nfunction callFuncAndCb(\n session: Collector.SessionData,\n collector?: Collector.Instance,\n cb?: SessionCallback | false,\n) {\n if (cb === false) return session; // Callback is disabled\n if (!cb) cb = defaultCb; // Default callback if none is provided\n return cb(session, collector, defaultCb);\n}\n\nfunction onConsentFn(config: SessionConfig, cb?: SessionCallback | false) {\n // Track the last processed group to prevent duplicate processing\n let lastProcessedGroup: string | undefined;\n\n const func = (collector: Collector.Instance, consent: WalkerOS.Consent) => {\n // Skip if we've already processed this group\n if (\n isDefined(lastProcessedGroup) &&\n lastProcessedGroup === collector?.group\n )\n return;\n\n // Remember this group has been processed\n lastProcessedGroup = collector?.group;\n\n let sessionFn: SessionFunction = () => sessionWindow(config); // Window by default\n\n if (config.consent) {\n const consentKeys = (\n isArray(config.consent) ? config.consent : [config.consent]\n ).reduce<WalkerOS.Consent>((acc, key) => ({ ...acc, [key]: true }), {});\n\n if (getGrantedConsent(consentKeys, consent))\n // Use storage if consent is granted\n sessionFn = () => sessionStorage(config);\n }\n\n return callFuncAndCb(sessionFn(), collector, cb);\n };\n\n return func;\n}\n\nconst defaultCb: SessionCallback = (\n session,\n collector,\n): Collector.SessionData => {\n const user: WalkerOS.User = {};\n\n // User.session is the session ID\n if (session.id) user.session = session.id;\n\n // Set device ID only in storage mode\n if (session.storage && session.device) user.device = session.device;\n\n // Set user IDs\n if (collector) {\n collector.command('user', user);\n }\n // No fallback - session source always provides collector\n\n if (session.isStart) {\n // Convert session start to an event object\n if (collector) {\n collector.push({\n name: 'session start',\n data: session,\n });\n }\n // No fallback - session source always provides collector\n }\n\n return session;\n};\n","import type { Source, Elb } from '@walkeros/core';\nimport type { SessionConfig, SessionCallback } from '../lib';\n\n// Settings: configuration for session source\nexport interface Settings extends SessionConfig {\n // All settings inherited from SessionConfig:\n // - consent?: string | string[]\n // - storage?: boolean\n // - cb?: SessionCallback | false\n // - pulse?: boolean\n // - sessionStorage?: 'local' | 'session'\n // - deviceStorage?: 'local' | 'session'\n // - sessionKey?: string\n // - deviceKey?: string\n // - length?: number (session timeout in minutes)\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\n// Re-export session types from lib\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from '../lib';\n","import type { Source, On, Collector } from '@walkeros/core';\nimport type { Types, Settings } from './types';\nimport { sessionStart } from './lib';\n\n// Export types for external usage\nexport * as SourceSession from './types';\n\n// Export lib functions for direct usage\nexport { sessionStart, sessionStorage, sessionWindow } from './lib';\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from './lib';\n\n/**\n * Session source implementation.\n *\n * This source handles session detection and management.\n */\nexport const sourceSession: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, command } = env;\n\n const settings: Settings = {\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Create minimal collector interface for sessionStart\n const collectorInterface: Partial<Collector.Instance> = {\n push: elb,\n group: undefined,\n command,\n };\n\n // Initialize session using local lib\n sessionStart({\n ...settings,\n collector: collectorInterface as Collector.Instance,\n });\n\n // Handle events pushed from collector (consent, session, ready, run)\n const handleEvent = async (event: On.Types) => {\n if (event === 'consent') {\n // Re-initialize session on consent changes\n sessionStart({\n ...settings,\n collector: collectorInterface as Collector.Instance,\n });\n }\n };\n\n return {\n type: 'session',\n config: fullConfig,\n push: elb,\n on: handleEvent,\n };\n};\n\nexport default sourceSession;\n"],"mappings":"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","names":["getId","sessionStorage","getId","session"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/sessionStorage.ts","../src/lib/sessionWindow.ts","../src/lib/sessionStart.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Collector } from '@walkeros/core';\nimport type { SessionWindowConfig } from './sessionWindow';\nimport type { StorageType } from '@walkeros/core';\nimport { getId, tryCatch } from '@walkeros/core';\nimport { storageRead, storageWrite } from '@walkeros/web-core';\nimport { sessionWindow } from './sessionWindow';\n\nexport interface SessionStorageConfig extends SessionWindowConfig {\n deviceKey?: string;\n deviceStorage?: StorageType;\n deviceAge?: number;\n sessionKey?: string;\n sessionStorage?: StorageType;\n length?: number; // Minutes after last update to consider session as expired (default: 30)\n pulse?: boolean;\n}\n\nexport function sessionStorage(\n config: SessionStorageConfig = {},\n): Collector.SessionData {\n const now = Date.now();\n const {\n length = 30, // Session length in minutes\n deviceKey = 'elbDeviceId',\n deviceStorage = 'local',\n deviceAge = 30, // Device ID age in days\n sessionKey = 'elbSessionId',\n sessionStorage = 'local',\n pulse = false, // Handle the counting\n } = config;\n const windowSession = sessionWindow(config); // Status based on window only\n let isStart = false;\n\n // Retrieve or create device ID\n const device = tryCatch((key: string, age: number, storage: StorageType) => {\n let id = storageRead(key, storage);\n if (!id) {\n id = getId(8); // Create a new device ID\n storageWrite(key, id, age * 1440, storage); // Write device ID to storage\n }\n return String(id);\n })(deviceKey, deviceAge, deviceStorage);\n\n // Retrieve or initialize session data\n const existingSession: Collector.SessionData =\n tryCatch(\n (key: string, storage?: StorageType) => {\n const session = JSON.parse(String(storageRead(key, storage)));\n\n // Only update session if it's not a pulse check\n if (pulse) return session;\n\n // Mark session as not new by default\n session.isNew = false;\n\n // Handle new marketing entry\n if (windowSession.marketing) {\n Object.assign(session, windowSession); // Overwrite existing session with marketing data\n isStart = true; // This is a session start\n }\n\n // Check if session is still active\n if (isStart || session.updated + length * 60000 < now) {\n // Session has expired\n delete session.id; // Unset session ID\n delete session.referrer; // Unset referrer\n session.start = now; // Set new session start\n session.count++; // Increase session count\n session.runs = 1; // Reset runs\n isStart = true; // It's a new session\n } else {\n // Session is still active\n session.runs++; // Increase number of runs\n }\n\n return session;\n },\n () => {\n // No existing session or something went wrong\n isStart = true; // Start a new session\n },\n )(sessionKey, sessionStorage) || {};\n\n // Default session data\n const defaultSession: Partial<Collector.SessionData> = {\n id: getId(12),\n start: now,\n isNew: true,\n count: 1,\n runs: 1,\n };\n\n // Merge session data\n const session = Object.assign(\n defaultSession, // Default session values\n windowSession, // Basic session data based on window\n existingSession, // (Updated) existing session\n { device }, // Device ID\n { isStart, storage: true, updated: now }, // Status of the session\n config.data, // Given data has the highest priority\n );\n\n // Write (updated) session to storage\n storageWrite(sessionKey, JSON.stringify(session), length * 2, sessionStorage);\n\n return session;\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport {\n getId,\n getMarketingParameters,\n type MarketingParameters,\n} from '@walkeros/core';\n\nexport interface SessionWindowConfig {\n data?: WalkerOS.Properties;\n domains?: string[];\n isStart?: boolean;\n parameters?: MarketingParameters;\n referrer?: string;\n url?: string;\n}\n\nexport function sessionWindow(\n config: SessionWindowConfig = {},\n): Collector.SessionData {\n let isStart = config.isStart || false;\n const known = { isStart, storage: false };\n\n // If session has explicitly started, return known\n if (config.isStart === false) return known;\n\n // Entry type\n if (!isStart) {\n // Only focus on linked or direct navigation types\n // and ignore reloads and all others\n const [perf] = performance.getEntriesByType(\n 'navigation',\n ) as PerformanceNavigationTiming[];\n if (perf.type !== 'navigate') return known;\n }\n\n const url = new URL(config.url || window.location.href);\n const ref = config.referrer || document.referrer;\n const referrer = ref && new URL(ref).hostname;\n\n // Marketing\n const marketing = getMarketingParameters(url, config.parameters);\n if (Object.keys(marketing).length) {\n // Check for marketing parameters like UTM and add existing\n if (!marketing.marketing)\n // Flag as a marketing session without overwriting\n marketing.marketing = true;\n\n isStart = true;\n }\n\n // Referrer\n if (!isStart) {\n // Small chance of multiple unintended events for same users\n // https://en.wikipedia.org/wiki/HTTP_referer#Referrer_hiding\n // Use domains: [''] to disable direct or hidden referrer\n\n const domains = config.domains || [];\n domains.push(url.hostname);\n isStart = !domains.includes(referrer);\n }\n\n return isStart\n ? // It's a session start, moin\n Object.assign(\n {\n isStart,\n storage: false,\n start: Date.now(),\n id: getId(12),\n referrer,\n },\n marketing,\n config.data,\n )\n : // No session start\n known;\n}\n","import type { Collector, WalkerOS, On } from '@walkeros/core';\nimport type { SessionStorageConfig } from './sessionStorage';\nimport { sessionStorage } from './sessionStorage';\nimport { sessionWindow } from './sessionWindow';\nimport { getGrantedConsent, isArray, isDefined } from '@walkeros/core';\n\nexport interface SessionConfig extends SessionStorageConfig {\n consent?: string | string[];\n storage?: boolean;\n cb?: SessionCallback | false;\n collector?: Collector.Instance;\n}\n\nexport type SessionFunction = typeof sessionStorage | typeof sessionWindow;\nexport type SessionCallback = (\n session: Collector.SessionData,\n collector: Collector.Instance | undefined,\n defaultCb: SessionCallback,\n) => void;\n\nexport function sessionStart(\n config: SessionConfig = {},\n): Collector.SessionData | void {\n const { cb, consent, collector, storage } = config;\n const sessionFn: SessionFunction = storage ? sessionStorage : sessionWindow;\n\n // Consent\n if (consent) {\n const consentHandler = onConsentFn(config, cb);\n\n const consentConfig = (\n isArray(consent) ? consent : [consent]\n ).reduce<On.ConsentConfig>(\n (acc, key) => ({ ...acc, [key]: consentHandler }),\n {},\n );\n // Register consent handlers with the collector\n if (collector) {\n collector.command('on', 'consent', consentConfig);\n }\n // No fallback - session source always provides collector\n } else {\n // just do it\n return callFuncAndCb(sessionFn(config), collector, cb);\n }\n}\n\nfunction callFuncAndCb(\n session: Collector.SessionData,\n collector?: Collector.Instance,\n cb?: SessionCallback | false,\n) {\n if (cb === false) return session; // Callback is disabled\n if (!cb) cb = defaultCb; // Default callback if none is provided\n return cb(session, collector, defaultCb);\n}\n\nfunction onConsentFn(config: SessionConfig, cb?: SessionCallback | false) {\n // Track the last processed group to prevent duplicate processing\n let lastProcessedGroup: string | undefined;\n\n const func = (collector: Collector.Instance, consent: WalkerOS.Consent) => {\n // Skip if we've already processed this group\n if (\n isDefined(lastProcessedGroup) &&\n lastProcessedGroup === collector?.group\n )\n return;\n\n // Remember this group has been processed\n lastProcessedGroup = collector?.group;\n\n let sessionFn: SessionFunction = () => sessionWindow(config); // Window by default\n\n if (config.consent) {\n const consentKeys = (\n isArray(config.consent) ? config.consent : [config.consent]\n ).reduce<WalkerOS.Consent>((acc, key) => ({ ...acc, [key]: true }), {});\n\n if (getGrantedConsent(consentKeys, consent))\n // Use storage if consent is granted\n sessionFn = () => sessionStorage(config);\n }\n\n return callFuncAndCb(sessionFn(), collector, cb);\n };\n\n return func;\n}\n\nconst defaultCb: SessionCallback = (\n session,\n collector,\n): Collector.SessionData => {\n const user: WalkerOS.User = {};\n\n // User.session is the session ID\n if (session.id) user.session = session.id;\n\n // Set device ID only in storage mode\n if (session.storage && session.device) user.device = session.device;\n\n // Set user IDs and broadcast session data\n if (collector) {\n collector.command('user', user);\n collector.command('session', session);\n }\n // No fallback - session source always provides collector\n\n if (session.isStart) {\n // Convert session start to an event object\n if (collector) {\n collector.push({\n name: 'session start',\n data: session,\n });\n }\n // No fallback - session source always provides collector\n }\n\n return session;\n};\n","import type { Source, Elb } from '@walkeros/core';\nimport type { SessionConfig, SessionCallback } from '../lib';\n\n// Settings: configuration for session source\nexport interface Settings extends SessionConfig {\n // All settings inherited from SessionConfig:\n // - consent?: string | string[]\n // - storage?: boolean\n // - cb?: SessionCallback | false\n // - pulse?: boolean\n // - sessionStorage?: 'local' | 'session'\n // - deviceStorage?: 'local' | 'session'\n // - sessionKey?: string\n // - deviceKey?: string\n // - length?: number (session timeout in minutes)\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\n// Re-export session types from lib\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from '../lib';\n","import type { Source, On, Collector } from '@walkeros/core';\nimport type { Types, Settings } from './types';\nimport { sessionStart } from './lib';\n\n// Export types for external usage\nexport * as SourceSession from './types';\n\n// Export lib functions for direct usage\nexport { sessionStart, sessionStorage, sessionWindow } from './lib';\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from './lib';\n\n/**\n * Session source implementation.\n *\n * This source handles session detection and management.\n */\nexport const sourceSession: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, command } = env;\n\n const settings: Settings = {\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Create minimal collector interface for sessionStart\n const collectorInterface: Partial<Collector.Instance> = {\n push: elb,\n group: undefined,\n command,\n };\n\n // Initialize session using local lib\n sessionStart({\n ...settings,\n collector: collectorInterface as Collector.Instance,\n });\n\n // Handle events pushed from collector (consent, session, ready, run)\n const handleEvent = async (event: On.Types) => {\n if (event === 'consent') {\n // Re-initialize session on consent changes\n sessionStart({\n ...settings,\n collector: collectorInterface as Collector.Instance,\n });\n }\n };\n\n return {\n type: 'session',\n config: fullConfig,\n push: elb,\n on: handleEvent,\n };\n};\n\nexport default sourceSession;\n"],"mappings":"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","names":["getId","sessionStorage","getId","session"]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$meta": {
|
|
3
|
+
"package": "@walkeros/web-source-session",
|
|
4
|
+
"version": "1.1.3",
|
|
5
|
+
"type": "source",
|
|
6
|
+
"platform": "web"
|
|
7
|
+
},
|
|
8
|
+
"schemas": {
|
|
9
|
+
"settings": {
|
|
10
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
11
|
+
"type": "object",
|
|
12
|
+
"properties": {
|
|
13
|
+
"storage": {
|
|
14
|
+
"default": false,
|
|
15
|
+
"description": "Enable persistent storage for session/device IDs",
|
|
16
|
+
"type": "boolean"
|
|
17
|
+
},
|
|
18
|
+
"consent": {
|
|
19
|
+
"anyOf": [
|
|
20
|
+
{
|
|
21
|
+
"type": "string"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "array",
|
|
25
|
+
"items": {
|
|
26
|
+
"type": "string"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"description": "Consent key(s) required to enable storage mode"
|
|
31
|
+
},
|
|
32
|
+
"length": {
|
|
33
|
+
"default": 30,
|
|
34
|
+
"description": "Session timeout in minutes",
|
|
35
|
+
"type": "number"
|
|
36
|
+
},
|
|
37
|
+
"pulse": {
|
|
38
|
+
"default": false,
|
|
39
|
+
"description": "Keep session alive on each event",
|
|
40
|
+
"type": "boolean"
|
|
41
|
+
},
|
|
42
|
+
"sessionKey": {
|
|
43
|
+
"default": "elbSessionId",
|
|
44
|
+
"description": "Storage key for session ID",
|
|
45
|
+
"type": "string"
|
|
46
|
+
},
|
|
47
|
+
"sessionStorage": {
|
|
48
|
+
"default": "local",
|
|
49
|
+
"description": "Storage type for session",
|
|
50
|
+
"type": "string",
|
|
51
|
+
"enum": [
|
|
52
|
+
"local",
|
|
53
|
+
"session"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"deviceKey": {
|
|
57
|
+
"default": "elbDeviceId",
|
|
58
|
+
"description": "Storage key for device ID",
|
|
59
|
+
"type": "string"
|
|
60
|
+
},
|
|
61
|
+
"deviceStorage": {
|
|
62
|
+
"default": "local",
|
|
63
|
+
"description": "Storage type for device",
|
|
64
|
+
"type": "string",
|
|
65
|
+
"enum": [
|
|
66
|
+
"local",
|
|
67
|
+
"session"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"deviceAge": {
|
|
71
|
+
"default": 30,
|
|
72
|
+
"description": "Device ID age in days",
|
|
73
|
+
"type": "number"
|
|
74
|
+
},
|
|
75
|
+
"cb": {
|
|
76
|
+
"description": "Custom session callback function or false to disable"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"additionalProperties": false
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"examples": {}
|
|
83
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/web-source-session",
|
|
3
3
|
"description": "Session source for walkerOS",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.4-next-1771252576264",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
@@ -25,15 +25,18 @@
|
|
|
25
25
|
"build": "tsup --silent",
|
|
26
26
|
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
|
|
27
27
|
"dev": "jest --watchAll --colors",
|
|
28
|
-
"
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"lint": "eslint \"**/*.ts*\"",
|
|
29
30
|
"test": "jest",
|
|
30
31
|
"update": "npx npm-check-updates -u && npm update"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@walkeros/core": "1.
|
|
34
|
-
"@walkeros/web-core": "1.0.
|
|
34
|
+
"@walkeros/core": "1.4.0-next-1771252576264",
|
|
35
|
+
"@walkeros/web-core": "1.0.6-next-1771252576264"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@walkeros/collector": "1.3.0-next-1771252576264"
|
|
35
39
|
},
|
|
36
|
-
"devDependencies": {},
|
|
37
40
|
"repository": {
|
|
38
41
|
"url": "git+https://github.com/elbwalker/walkerOS.git",
|
|
39
42
|
"directory": "packages/web/sources/session"
|
|
@@ -43,11 +46,16 @@
|
|
|
43
46
|
"bugs": {
|
|
44
47
|
"url": "https://github.com/elbwalker/walkerOS/issues"
|
|
45
48
|
},
|
|
49
|
+
"walkerOS": {
|
|
50
|
+
"type": "source",
|
|
51
|
+
"platform": "web"
|
|
52
|
+
},
|
|
46
53
|
"keywords": [
|
|
47
|
-
"walker",
|
|
48
54
|
"walkerOS",
|
|
55
|
+
"walkerOS-source",
|
|
49
56
|
"source",
|
|
50
57
|
"web",
|
|
51
|
-
"session"
|
|
58
|
+
"session",
|
|
59
|
+
"analytics"
|
|
52
60
|
]
|
|
53
61
|
}
|
package/dist/chunk-J5LGTIGS.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|