Skip to content

Commit 6e6651b

Browse files
addDestination util
1 parent 8a26058 commit 6e6651b

File tree

10 files changed

+83
-76
lines changed

10 files changed

+83
-76
lines changed

packages/sources/walkerjs/src/__tests__/destination.test.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,8 @@ describe('Destination', () => {
314314
elb('foo bar');
315315

316316
const eventMapping = { data: { value: 'bar' } };
317-
await elb(
317+
318+
elb(
318319
'walker destination',
319320
{ push: mockPush },
320321
{
@@ -323,6 +324,8 @@ describe('Destination', () => {
323324
},
324325
);
325326

327+
await jest.runAllTimersAsync();
328+
326329
// Event data
327330
expect(mockPush).toHaveBeenCalledWith(
328331
expect.objectContaining({ event: 'foo bar' }),
@@ -347,7 +350,7 @@ describe('Destination', () => {
347350
elb('foo bar');
348351

349352
const eventMapping = { data: { map: { foo: { value: 'bar' } } } };
350-
await elb(
353+
elb(
351354
'walker destination',
352355
{ push: mockPush },
353356
{
@@ -356,6 +359,7 @@ describe('Destination', () => {
356359
},
357360
);
358361

362+
await jest.runAllTimersAsync();
359363
expect(mockPush).toHaveBeenCalledWith(
360364
expect.any(Object),
361365
expect.any(Object),
@@ -838,6 +842,7 @@ describe('Destination', () => {
838842

839843
await elb('entity action');
840844
expect(mockDataLayer).toHaveBeenCalledTimes(0);
845+
841846
await elb('walker consent', { functional: true });
842847
expect(mockDataLayer).toHaveBeenCalledTimes(1);
843848

@@ -945,7 +950,6 @@ describe('Destination', () => {
945950
});
946951

947952
await elb(event);
948-
949953
expect(mockPush).toHaveBeenCalledWith({
950954
...event,
951955
event: 'new name',

packages/sources/walkerjs/src/__tests__/trigger.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ describe('Trigger', () => {
5555
const { elb } = createSourceWalkerjs({ default: true, session: false });
5656

5757
// Both e load events should be triggered
58-
await elb('walker init');
58+
elb('walker init');
59+
await jest.runAllTimersAsync();
5960
expect(mockDataLayer).toHaveBeenCalledWith(
6061
expect.objectContaining({
6162
event: 'e all',
@@ -72,6 +73,7 @@ describe('Trigger', () => {
7273

7374
// Only the e init event should be triggered
7475
await elb('walker init', elem);
76+
await jest.runAllTimersAsync();
7577
expect(mockDataLayer).not.toHaveBeenCalledWith(
7678
expect.objectContaining({ event: 'e all' }),
7779
);

packages/sources/walkerjs/src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { Elb, SourceWalkerjs } from './types';
2-
import { onApply } from '@elbwalker/utils';
2+
import { addDestination, onApply } from '@elbwalker/utils';
33
import { sessionStart } from '@elbwalker/utils/web';
4-
import { addDestination } from './lib/destination';
54
import { createPush, elbLayerInit } from './lib/push';
65
import { run } from './lib/run';
76
import { createSessionStart } from './lib/session';

packages/sources/walkerjs/src/lib/destination.ts

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,4 @@
1-
import type { SourceWalkerjs, DestinationWeb } from '../types';
2-
import { getId, pushToDestinations } from '@elbwalker/utils';
3-
4-
export async function addDestination(
5-
instance: SourceWalkerjs.Instance,
6-
data: DestinationWeb.DestinationInit,
7-
options?: DestinationWeb.Config,
8-
) {
9-
// Prefer explicit given config over default config
10-
const config = options || data.config || { init: false };
11-
12-
const destination: DestinationWeb.Destination = {
13-
...data,
14-
config,
15-
};
16-
17-
let id = config.id; // Use given id
18-
if (!id) {
19-
// Generate a new id if none was given
20-
do {
21-
id = getId(4);
22-
} while (instance.destinations[id]);
23-
}
24-
25-
// Add the destination
26-
instance.destinations[id] = destination;
27-
28-
// Process previous events if not disabled
29-
if (config.queue !== false) destination.queue = [...instance.queue];
30-
return await pushToDestinations(instance, { destination });
31-
}
1+
import type { DestinationWeb } from '../types';
322

333
export function dataLayerDestination() {
344
window.dataLayer = window.dataLayer || [];

packages/sources/walkerjs/src/lib/handle.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Hooks, On, WalkerOS } from '@elbwalker/types';
22
import type { SourceWalkerjs, DestinationWeb, Elb } from '../types';
33
import {
44
Const,
5+
addDestination,
56
assign,
67
isArray,
78
isElementOrDocument,
@@ -14,7 +15,6 @@ import {
1415
} from '@elbwalker/utils';
1516
import { initScopeTrigger, ready } from './trigger';
1617
import { getState } from './state';
17-
import { addDestination } from './destination';
1818
import { run } from './run';
1919
import { addHook } from './hooks';
2020

@@ -40,18 +40,21 @@ export async function handleCommand(
4040
).config;
4141
break;
4242
case Const.Commands.Consent:
43-
if (isObject(data)) setConsent(instance, data as WalkerOS.Consent);
43+
if (isObject(data)) {
44+
const foo = await setConsent(instance, data as WalkerOS.Consent);
45+
}
4446
break;
4547
case Const.Commands.Custom:
4648
if (isObject(data)) instance.custom = assign(instance.custom, data);
4749
break;
4850
case Const.Commands.Destination:
49-
isObject(data) &&
50-
addDestination(
51+
if (isObject(data)) {
52+
await addDestination(
5153
instance,
5254
data as DestinationWeb.Destination,
5355
options as DestinationWeb.Config,
5456
);
57+
}
5558
break;
5659
case Const.Commands.Globals:
5760
if (isObject(data)) instance.globals = assign(instance.globals, data);
@@ -71,16 +74,23 @@ export async function handleCommand(
7174
on(instance, data as On.Types, options as On.Options);
7275
break;
7376
case Const.Commands.Run:
74-
ready(instance, run, instance, data as Partial<SourceWalkerjs.State>);
77+
await ready(
78+
instance,
79+
run,
80+
instance,
81+
data as Partial<SourceWalkerjs.State>,
82+
);
7583
break;
7684
case Const.Commands.User:
7785
if (isObject(data)) assign(instance.user, data, { shallow: false });
7886
break;
7987
default:
8088
break;
8189
}
90+
8291
result.status.ok = true;
8392

93+
// @TODO return result
8494
return result;
8595
}
8696

@@ -105,11 +115,7 @@ export async function handleEvent(
105115
// Add event to internal queue
106116
instance.queue.push(event);
107117

108-
const foo = await pushToDestinations(
109-
instance,
110-
instance.destinations,
111-
event,
112-
);
118+
await pushToDestinations(instance, instance.destinations, event);
113119

114120
result.status.ok = true;
115121
})();

packages/sources/walkerjs/src/lib/trigger.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,21 @@ export const Trigger: { [key: string]: Walker.Trigger } = {
3636
Wait: 'wait',
3737
} as const;
3838

39-
export function ready<T extends (...args: never[]) => R, R>(
39+
export async function ready<T extends (...args: never[]) => R, R>(
4040
instance: SourceWalkerjs.Instance,
4141
fn: T,
4242
...args: Parameters<T>
43-
): void {
43+
): Promise<R | undefined> {
4444
const readyFn = () => {
45-
fn(...args);
45+
const result = fn(...args);
4646
onApply(instance, 'ready');
47+
return result;
4748
};
4849

4950
if (document.readyState !== 'loading') {
50-
readyFn();
51+
return readyFn();
5152
} else {
5253
document.addEventListener('DOMContentLoaded', readyFn);
53-
return;
5454
}
5555
}
5656

packages/sources/walkerjs/src/types/destination.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ export interface Destination<Custom = unknown, CustomEvent = unknown>
1010
init?: WalkerOSDestination.InitFn<Custom, CustomEvent>;
1111
}
1212

13-
export type DestinationInit = Partial<Omit<Destination, 'push'>> &
14-
Pick<Destination, 'push'>;
13+
export type DestinationInit = WalkerOSDestination.DestinationInit;
1514

1615
// @TODO move to WalkerOSDestination
1716
// check if used

packages/types/src/destination.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ export interface Policy {
3535
[key: string]: Mapping.Value;
3636
}
3737

38+
export type DestinationInit = Partial<Omit<Destination, 'push'>> &
39+
Pick<Destination, 'push'>;
40+
3841
export type InitFn<Custom, CustomEvent> = (
3942
config?: PartialConfig<Custom, CustomEvent>,
4043
instance?: WalkerOS.Instance,

packages/utils/src/core/destination.ts

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,44 @@ import type {
44
WalkerOS,
55
Elb,
66
} from '@elbwalker/types';
7-
import {
8-
getMappingEvent,
9-
getMappingValue,
10-
isDefined,
11-
assign,
12-
isObject,
13-
useHooks,
14-
debounce,
15-
setByPath,
16-
getGrantedConsent,
17-
tryCatchAsync,
18-
} from './index';
7+
import { getId } from './getId';
8+
import { setByPath } from './byPath';
9+
import { getMappingEvent, getMappingValue } from './mapping';
10+
import { getGrantedConsent } from './consent';
11+
import { tryCatchAsync } from './tryCatch';
12+
import { assign } from './assign';
13+
import { useHooks } from './useHooks';
14+
import { isDefined, isObject } from './is';
15+
import { debounce } from './invocations';
16+
17+
export async function addDestination(
18+
instance: WalkerOS.Instance,
19+
data: WalkerOSDestination.DestinationInit,
20+
options?: WalkerOSDestination.Config,
21+
) {
22+
// Prefer explicit given config over default config
23+
const config = options || data.config || { init: false };
24+
25+
const destination: WalkerOSDestination.Destination = {
26+
...data,
27+
config,
28+
};
29+
30+
let id = config.id; // Use given id
31+
if (!id) {
32+
// Generate a new id if none was given
33+
do {
34+
id = getId(4);
35+
} while (instance.destinations[id]);
36+
}
37+
38+
// Add the destination
39+
instance.destinations[id] = destination;
40+
41+
// Process previous events if not disabled
42+
if (config.queue !== false) destination.queue = [...instance.queue];
43+
return pushToDestinations(instance, { destination });
44+
}
1945

2046
export async function pushToDestinations(
2147
instance: WalkerOS.Instance,
@@ -41,14 +67,13 @@ export async function pushToDestinations(
4167
// Add event to queue stack
4268
if (event) {
4369
// Policy check
44-
Object.entries(destination.config.policy || []).forEach(
45-
([key, mapping]) => {
46-
setByPath(
47-
event,
48-
key,
49-
getMappingValue(event, mapping, { instance }),
50-
);
51-
},
70+
await Promise.all(
71+
Object.entries(destination.config.policy || []).map(
72+
async ([key, mapping]) => {
73+
const value = await getMappingValue(event, mapping, { instance });
74+
setByPath(event, key, value);
75+
},
76+
),
5277
);
5378

5479
queue.push(event);

packages/utils/src/core/mapping.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getGrantedConsent } from './consent';
33
import { getByPath } from './byPath';
44
import { isArray, isDefined, isString, isObject } from './is';
55
import { castToProperty } from './property';
6-
import { tryCatch, tryCatchAsync } from './tryCatch';
6+
import { tryCatchAsync } from './tryCatch';
77

88
export async function getMappingEvent(
99
event: WalkerOS.PartialEvent,
@@ -71,7 +71,6 @@ export async function getMappingValue(
7171
...options,
7272
consent: consentState,
7373
});
74-
7574
if (isDefined(result)) return result;
7675
}
7776
}

0 commit comments

Comments
 (0)