@goodgamestudios/cxf-webshop 7.0.0-qa.2 → 7.0.0-qa.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/cdn.jsdelivr.net/npm/@goodgamestudios/cxf-webshop@qa/dist/webshop-cxf.js +1499 -0
- package/dist/webshop-cxf.js +1247 -1
- package/dist/webshop-cxf.js.map +4 -4
- package/package.json +127 -127
- package/.eslintrc.js +0 -25
- package/.prettierignore +0 -6
- package/.prettierrc.js +0 -10
- package/REFACTORING_README.md +0 -265
- package/TEST_MIGRATION.md +0 -441
- package/TYPES_REFACTORING.md +0 -308
- package/esbuild.build.js +0 -14
- package/esbuild.serve.js +0 -25
- package/src_old/@types/global.d.ts +0 -2
- package/src_old/ArgumentNullError.ts +0 -6
- package/src_old/app.ts +0 -30
- package/src_old/combineReaders.ts +0 -8
- package/src_old/common.ts +0 -35
- package/src_old/config.ts +0 -42
- package/src_old/cxf.ts +0 -32
- package/src_old/dialog.ts +0 -25
- package/src_old/env.ts +0 -127
- package/src_old/fetch.ts +0 -46
- package/src_old/handlers/eventHandlers.ts +0 -43
- package/src_old/handlers/postMessageHandlers.ts +0 -43
- package/src_old/handlers/pushHandlers.ts +0 -95
- package/src_old/handlers/reducers.ts +0 -207
- package/src_old/helpers.ts +0 -143
- package/src_old/index.ts +0 -35
- package/src_old/messages/IShopMessageBus.ts +0 -3
- package/src_old/messages/ShopMessageBus.ts +0 -10
- package/src_old/messages/TestShopMessageBus.ts +0 -8
- package/src_old/ping.ts +0 -15
- package/src_old/preFetch.ts +0 -43
- package/src_old/storage.ts +0 -32
- package/src_old/store.ts +0 -82
- package/src_old/track.ts +0 -59
- package/src_old/url.ts +0 -95
- package/src_old/utils.ts +0 -64
package/src_old/fetch.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { DIReader } from './common'
|
|
2
|
-
import { inject } from 'readuz'
|
|
3
|
-
import { criteriaSelector } from './store'
|
|
4
|
-
|
|
5
|
-
export type OfferNotificationsFetchResult = () => void
|
|
6
|
-
export const fetchUnreadOfferNotificationsCount: DIReader<OfferNotificationsFetchResult> = inject(
|
|
7
|
-
(environment) => environment.log,
|
|
8
|
-
(environment) => environment.logError,
|
|
9
|
-
(environment) => environment.getStore,
|
|
10
|
-
(environment) => environment.config,
|
|
11
|
-
(log, logError, getStore, { LEGEND_LEVEL_IS_USED }) =>
|
|
12
|
-
async () => {
|
|
13
|
-
const store = getStore()
|
|
14
|
-
if (LEGEND_LEVEL_IS_USED && store.legendLevel === undefined) {
|
|
15
|
-
log('Skip fetchUnreadOfferNotificationsCount due to legendLevel is undefined')
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
log('fetchUnreadOfferNotificationsCount')
|
|
19
|
-
if (store.token && store.unreadOfferNotifsCountUrl) {
|
|
20
|
-
let unreadCount = 0
|
|
21
|
-
const headers = {
|
|
22
|
-
Authorization: `Bearer ${store.token}`,
|
|
23
|
-
}
|
|
24
|
-
const url = store.unreadOfferNotifsCountUrl
|
|
25
|
-
.replace('{locale}', store.language || '')
|
|
26
|
-
.replace('{zoneId}', store.zoneId || '')
|
|
27
|
-
.replace('{criteria}', encodeURIComponent(JSON.stringify(criteriaSelector(store))))
|
|
28
|
-
try {
|
|
29
|
-
log('fetch', url)
|
|
30
|
-
const resp = await fetch(url, {
|
|
31
|
-
headers,
|
|
32
|
-
})
|
|
33
|
-
if (resp.ok) {
|
|
34
|
-
const data = await resp.json()
|
|
35
|
-
unreadCount = Number(data?.notifCount)
|
|
36
|
-
}
|
|
37
|
-
} catch (error) {
|
|
38
|
-
logError(`cannot fetch ${url}`, error)
|
|
39
|
-
}
|
|
40
|
-
log('setUnseenOffersCounter', unreadCount)
|
|
41
|
-
store.gameApi.invokeFn('setUnseenOffersCounter', unreadCount).catch((error) => {
|
|
42
|
-
logError('setUnseenOffersCounter error:', error)
|
|
43
|
-
})
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
)
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { inject } from 'readuz'
|
|
2
|
-
import { DIReader } from '../common'
|
|
3
|
-
import { createSessionId } from '../helpers'
|
|
4
|
-
|
|
5
|
-
export interface OpenIGSPayload {
|
|
6
|
-
page?: string
|
|
7
|
-
route?: string
|
|
8
|
-
sourceId?: string
|
|
9
|
-
config?: Record<string, any>
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type OnOpen = (payload?: OpenIGSPayload) => void
|
|
13
|
-
export const onOpen: DIReader<OnOpen> = inject(
|
|
14
|
-
(environment) => environment.createIframeUrl,
|
|
15
|
-
(environment) => environment.createDialog,
|
|
16
|
-
(environment) => environment.log,
|
|
17
|
-
(environment) => environment.trackOpenAction,
|
|
18
|
-
(environment) => environment.getStore,
|
|
19
|
-
(environment) => environment.setStore,
|
|
20
|
-
(createIframeUrl, createDialog, log, trackOpenAction, getStore, setStore) =>
|
|
21
|
-
(payload = {}) => {
|
|
22
|
-
log('OnOpen payload:', payload)
|
|
23
|
-
if (payload.sourceId) {
|
|
24
|
-
setStore({
|
|
25
|
-
sourceId: payload.sourceId,
|
|
26
|
-
})
|
|
27
|
-
}
|
|
28
|
-
const store = getStore()
|
|
29
|
-
const sid = createSessionId()
|
|
30
|
-
trackOpenAction(sid)
|
|
31
|
-
const url = createIframeUrl({
|
|
32
|
-
sid,
|
|
33
|
-
page: store.lastPurchaseTab,
|
|
34
|
-
...payload,
|
|
35
|
-
})
|
|
36
|
-
createDialog(url)
|
|
37
|
-
setTimeout(() => {
|
|
38
|
-
// remove unread offer notifications counter on the IGS button while opening the IGS
|
|
39
|
-
// small delay makes UX a bit better due to it happens after IGS initialization is started
|
|
40
|
-
store.gameApi.invokeFn('setUnseenOffersCounter', 0)
|
|
41
|
-
}, 1000)
|
|
42
|
-
}
|
|
43
|
-
)
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { inject } from 'readuz'
|
|
2
|
-
import { DIReader, WebshopEvents, IDictionary } from '../common'
|
|
3
|
-
import { combineReaders } from '../combineReaders'
|
|
4
|
-
import { createSessionId } from '../helpers'
|
|
5
|
-
|
|
6
|
-
export type OpenSalesPage = () => void
|
|
7
|
-
export const onSalesPageOpen: DIReader<OpenSalesPage> = inject(
|
|
8
|
-
(environment) => environment.log,
|
|
9
|
-
(environment) => environment.createDialog,
|
|
10
|
-
(environment) => environment.createIframeUrl,
|
|
11
|
-
(log, createDialog, createIframeUrl) => () => {
|
|
12
|
-
log('OnOpenSalesOffersPage')
|
|
13
|
-
const sid = createSessionId()
|
|
14
|
-
const url = createIframeUrl({
|
|
15
|
-
page: 'sale-offers',
|
|
16
|
-
sid,
|
|
17
|
-
})
|
|
18
|
-
createDialog(url)
|
|
19
|
-
}
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
export type LemonstandClose = () => void
|
|
23
|
-
export const onLemonstandClose: DIReader<LemonstandClose> = inject(
|
|
24
|
-
(environment) => environment.log,
|
|
25
|
-
(environment) => environment.getStore,
|
|
26
|
-
(environment) => environment.fetchUnreadOfferNotificationsCount,
|
|
27
|
-
(log, getStore, fetchUnreadOfferNotificationsCount) => () => {
|
|
28
|
-
const store = getStore()
|
|
29
|
-
log('onLemonstandClose', store)
|
|
30
|
-
fetchUnreadOfferNotificationsCount()
|
|
31
|
-
}
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
export type Handler = (...arguments_: any[]) => void
|
|
35
|
-
export type Handlers = IDictionary<Handler>
|
|
36
|
-
|
|
37
|
-
export function createPostMessageHandlers(handlers: IDictionary<DIReader<Handler>>) {
|
|
38
|
-
return combineReaders({
|
|
39
|
-
[WebshopEvents.CXF_OPEN_SALES_MSG]: onSalesPageOpen,
|
|
40
|
-
[WebshopEvents.CXF_DIALOG_CLOSE]: onLemonstandClose,
|
|
41
|
-
...handlers,
|
|
42
|
-
})
|
|
43
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { DIReader, WebshopEvents, IDictionary } from '../common'
|
|
2
|
-
import { combineReaders } from '../combineReaders'
|
|
3
|
-
import { inject } from 'readuz'
|
|
4
|
-
|
|
5
|
-
interface OnRewardProperties {
|
|
6
|
-
successUrl: string
|
|
7
|
-
offerId: string
|
|
8
|
-
sid: string
|
|
9
|
-
page: string
|
|
10
|
-
config?: Record<string, any>
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export type OnReward = (properties: OnRewardProperties) => void
|
|
14
|
-
export const onReward: DIReader<OnReward> = inject(
|
|
15
|
-
(environment) => environment.log,
|
|
16
|
-
(environment) => environment.createDialog,
|
|
17
|
-
(environment) => environment.createIframeUrl,
|
|
18
|
-
(environment) => environment.setStore,
|
|
19
|
-
(environment) => environment.trackOpenAction,
|
|
20
|
-
(log, createDialog, createIframeUrl, setStore, trackOpenAction) => (payload) => {
|
|
21
|
-
log('OnReward: offerId', payload.offerId, 'Page', payload.page)
|
|
22
|
-
const url = createIframeUrl({
|
|
23
|
-
route: encodeURIComponent(payload.successUrl),
|
|
24
|
-
...payload,
|
|
25
|
-
})
|
|
26
|
-
setStore({
|
|
27
|
-
lastPurchaseTab: payload.page,
|
|
28
|
-
sourceId: 'successfulPayoutReward',
|
|
29
|
-
})
|
|
30
|
-
trackOpenAction(payload.sid)
|
|
31
|
-
|
|
32
|
-
createDialog(url)
|
|
33
|
-
}
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
export interface OnLemonstandCategoryUpdateProperties {
|
|
37
|
-
target: string
|
|
38
|
-
action: string
|
|
39
|
-
data: any
|
|
40
|
-
}
|
|
41
|
-
export type OnLemonstandCategoryUpdate = (properties: OnLemonstandCategoryUpdateProperties) => void
|
|
42
|
-
export const onLemonstandCategoryUpdate: DIReader<OnLemonstandCategoryUpdate> = inject(
|
|
43
|
-
(environment) => environment.shopMessageBus,
|
|
44
|
-
(shopMessageBus) =>
|
|
45
|
-
({ target, action, data }) => {
|
|
46
|
-
shopMessageBus.post({
|
|
47
|
-
eventName: WebshopEvents.LEMONSTAND_CATEGORY_UPDATE,
|
|
48
|
-
target,
|
|
49
|
-
data: { action, data },
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
export interface OnLemonstandNotificationsCreatedProperties {
|
|
55
|
-
notifCount: number
|
|
56
|
-
}
|
|
57
|
-
type OnLemonstandNotificationsCreated = (properties: OnLemonstandNotificationsCreatedProperties) => void
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* this handler works in case of offer notification activation and deactivation
|
|
61
|
-
*/
|
|
62
|
-
export const onLemonstandNotificationsCreated: DIReader<OnLemonstandNotificationsCreated> = inject(
|
|
63
|
-
(environment) => environment.log,
|
|
64
|
-
(environment) => environment.logError,
|
|
65
|
-
(environment) => environment.getStore,
|
|
66
|
-
(environment) => environment.fetchUnreadOfferNotificationsCount,
|
|
67
|
-
(log, logError, getStore, fetchUnreadOfferNotificationsCount) =>
|
|
68
|
-
({ notifCount }) => {
|
|
69
|
-
log('onLemonstandNotificationsCreated -> notifCount:', notifCount)
|
|
70
|
-
const store = getStore()
|
|
71
|
-
if (notifCount > 0) {
|
|
72
|
-
// random delay in range 1-120 sec on LIVE, and 1-15 sec on TEST
|
|
73
|
-
const randomDelayMs = Math.floor(Math.random() * (Number(store.networkId) < 250 ? 120_000 : 15_000))
|
|
74
|
-
setTimeout(() => {
|
|
75
|
-
fetchUnreadOfferNotificationsCount()
|
|
76
|
-
}, randomDelayMs)
|
|
77
|
-
} else {
|
|
78
|
-
store.gameApi.invokeFn('setUnseenOffersCounter', 0).catch((error) => {
|
|
79
|
-
logError('setUnseenOffersCounter error:', error)
|
|
80
|
-
})
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
export type PushHandler = (...arguments_: any[]) => void
|
|
86
|
-
export type PushHandlers = IDictionary<PushHandler>
|
|
87
|
-
|
|
88
|
-
export function createPushHandlers(handlers: IDictionary<DIReader<PushHandler>>) {
|
|
89
|
-
return combineReaders({
|
|
90
|
-
reward: onReward,
|
|
91
|
-
[WebshopEvents.LEMONSTAND_CATEGORY_UPDATE]: onLemonstandCategoryUpdate,
|
|
92
|
-
[WebshopEvents.LEMONSTAND_NOTIFICATIONS_CREATED]: onLemonstandNotificationsCreated,
|
|
93
|
-
...handlers,
|
|
94
|
-
})
|
|
95
|
-
}
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { inject, Reader } from 'readuz'
|
|
2
|
-
import { CxfEvents, IGameEvent, ILoginData } from '@goodgamestudios/cxf-events'
|
|
3
|
-
import { DIReader, WebshopEvents, IDictionary, IPushMessageData } from '../common'
|
|
4
|
-
import { combineReaders } from '../combineReaders'
|
|
5
|
-
|
|
6
|
-
export type SubscribeToCxf = Reader<void, void>
|
|
7
|
-
const commonCxfReducer: DIReader<SubscribeToCxf> = inject(
|
|
8
|
-
(environment) => environment.log,
|
|
9
|
-
(environment) => environment.getCxf,
|
|
10
|
-
(environment) => environment.onOpen,
|
|
11
|
-
(environment) => environment.tryCatch,
|
|
12
|
-
(environment) => environment.pushHandlers,
|
|
13
|
-
(log, getCxf, onOpen, tryCatch, pushHandlers) => () => {
|
|
14
|
-
const cxf = getCxf()
|
|
15
|
-
cxf.on(CxfEvents.OpenIGS, tryCatch(onOpen))
|
|
16
|
-
cxf.on(
|
|
17
|
-
CxfEvents.Push,
|
|
18
|
-
tryCatch(({ id, payload }: IPushMessageData) => {
|
|
19
|
-
log('cxf.push', id, payload)
|
|
20
|
-
const handler = pushHandlers[id]
|
|
21
|
-
handler && handler(payload)
|
|
22
|
-
})
|
|
23
|
-
)
|
|
24
|
-
}
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
export type CxfReducers = IDictionary<SubscribeToCxf>
|
|
28
|
-
|
|
29
|
-
export function createCxfReducers(handlers: IDictionary<DIReader<SubscribeToCxf>>) {
|
|
30
|
-
return combineReaders({
|
|
31
|
-
common: commonCxfReducer,
|
|
32
|
-
gameEvents: subscribeToGameEvents,
|
|
33
|
-
...handlers,
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export type SubscribeToGameEvents = () => void
|
|
38
|
-
export const subscribeToGameEvents: DIReader<SubscribeToGameEvents> = inject(
|
|
39
|
-
(environment) => environment.log,
|
|
40
|
-
(environment) => environment.logError,
|
|
41
|
-
(environment) => environment.getCxf,
|
|
42
|
-
(environment) => environment.getStore,
|
|
43
|
-
(environment) => environment.setStore,
|
|
44
|
-
(environment) => environment.fetchUnreadOfferNotificationsCount,
|
|
45
|
-
(log, logError, getCxf, getStore, setStore, fetchUnreadOfferNotificationsCount) => () => {
|
|
46
|
-
const cxf = getCxf()
|
|
47
|
-
cxf.on(CxfEvents.Login, (e: ILoginData) => {
|
|
48
|
-
const { gameEvents } = getStore()
|
|
49
|
-
const { gameEvents: eventsInLogin } = e
|
|
50
|
-
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
51
|
-
const eventNotExistPredicateGenerator = (existingEvents: IGameEvent[]) => (event: IGameEvent) =>
|
|
52
|
-
!existingEvents.map((event_) => event_.type).includes(event.type)
|
|
53
|
-
setStore({
|
|
54
|
-
...e,
|
|
55
|
-
gameEvents: [...gameEvents.filter(eventNotExistPredicateGenerator(eventsInLogin)), ...eventsInLogin],
|
|
56
|
-
})
|
|
57
|
-
log(CxfEvents.Login, 'reducer', getStore())
|
|
58
|
-
fetchUnreadOfferNotificationsCount()
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
cxf.on(CxfEvents.GameEventUpdate, (e: IGameEvent[]) => {
|
|
62
|
-
log(CxfEvents.GameEventUpdate, e)
|
|
63
|
-
const store = getStore()
|
|
64
|
-
const updatedEventTypes = new Set(e.map((event) => event.type))
|
|
65
|
-
setStore({
|
|
66
|
-
gameEvents: [...store.gameEvents.filter((event) => !updatedEventTypes.has(event.type)), ...e],
|
|
67
|
-
})
|
|
68
|
-
log(CxfEvents.GameEventUpdate, 'reducer', getStore())
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
cxf.on(CxfEvents.GameEventAdd, (e: IGameEvent) => {
|
|
72
|
-
log(CxfEvents.GameEventAdd, e)
|
|
73
|
-
const store = getStore()
|
|
74
|
-
setStore({
|
|
75
|
-
gameEvents: [...store.gameEvents, e],
|
|
76
|
-
})
|
|
77
|
-
log(CxfEvents.GameEventAdd, 'reducer', getStore())
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
cxf.on(CxfEvents.GameEventRemove, (e: number) => {
|
|
81
|
-
log(CxfEvents.GameEventRemove, e)
|
|
82
|
-
const store = getStore()
|
|
83
|
-
setStore({
|
|
84
|
-
gameEvents: store.gameEvents.filter(({ type }) => type !== e),
|
|
85
|
-
})
|
|
86
|
-
log(CxfEvents.GameEventRemove, 'reducer', getStore())
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
cxf.on(CxfEvents.LevelChanged, (level: number) => {
|
|
90
|
-
log(CxfEvents.LevelChanged, level)
|
|
91
|
-
setStore({
|
|
92
|
-
level,
|
|
93
|
-
})
|
|
94
|
-
log(CxfEvents.LevelChanged, 'reducer', getStore())
|
|
95
|
-
fetchUnreadOfferNotificationsCount()
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
cxf.on(CxfEvents.LegendLevelChanged, (legendLevel: number) => {
|
|
99
|
-
log(CxfEvents.LegendLevelChanged, `legendLevel: ${legendLevel}`)
|
|
100
|
-
setStore({
|
|
101
|
-
legendLevel,
|
|
102
|
-
})
|
|
103
|
-
const store = getStore()
|
|
104
|
-
log(CxfEvents.LegendLevelChanged, 'reducer', store)
|
|
105
|
-
fetchUnreadOfferNotificationsCount()
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
/*
|
|
111
|
-
In E4K this event is used to control the subscriptions tab
|
|
112
|
-
This is deprecated, as specific config values/tab visibility can be controlled using Lemonstands `config` query param
|
|
113
|
-
*/
|
|
114
|
-
|
|
115
|
-
export const nativeSubscriptionEnableReducer: DIReader<SubscribeToCxf> = inject(
|
|
116
|
-
(environment) => environment.getCxf,
|
|
117
|
-
(environment) => environment.setStore,
|
|
118
|
-
(environment) => environment.preResolveConfig,
|
|
119
|
-
(getCxf, setStore, preResolveConfig) => () => {
|
|
120
|
-
const cxf = getCxf()
|
|
121
|
-
cxf.on(WebshopEvents.CXF_NATIVE_SUBSCRIPTION_ENABLE, (enabled: 0 | 1) => {
|
|
122
|
-
setStore({
|
|
123
|
-
subscriptionDisabled: enabled === 0,
|
|
124
|
-
customizationSuffix: enabled === 0 ? 'no-subscription' : '',
|
|
125
|
-
})
|
|
126
|
-
preResolveConfig()
|
|
127
|
-
})
|
|
128
|
-
}
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
/*
|
|
132
|
-
The config file suffix (e.g. "em.json" + "mobile" -> "em-mobile.json") can be set through an event
|
|
133
|
-
Used by MS and BFW integration pages
|
|
134
|
-
*/
|
|
135
|
-
|
|
136
|
-
export const setCustomizationSuffixReducer: DIReader<SubscribeToCxf> = inject(
|
|
137
|
-
(environment) => environment.getCxf,
|
|
138
|
-
(environment) => environment.getStore,
|
|
139
|
-
(environment) => environment.setStore,
|
|
140
|
-
(environment) => environment.preResolveConfig,
|
|
141
|
-
(getCxf, getStore, setStore, preResolveConfig) => () => {
|
|
142
|
-
const cxf = getCxf()
|
|
143
|
-
cxf.on(WebshopEvents.CXF_SET_CUSTOMIZATION_SUFFIX, (suffix: string) => {
|
|
144
|
-
const store = getStore()
|
|
145
|
-
if (suffix === store.customizationSuffix) {
|
|
146
|
-
return
|
|
147
|
-
}
|
|
148
|
-
setStore({
|
|
149
|
-
customizationSuffix: suffix || '',
|
|
150
|
-
})
|
|
151
|
-
preResolveConfig()
|
|
152
|
-
})
|
|
153
|
-
}
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
/*
|
|
157
|
-
Information about whether ads are enabled or not is retrieved externally from `cxf-ad-banners`
|
|
158
|
-
and stored to be passed to IGS
|
|
159
|
-
*/
|
|
160
|
-
|
|
161
|
-
export const receiveAdStatusReducer: DIReader<SubscribeToCxf> = inject(
|
|
162
|
-
(environment) => environment.getCxf,
|
|
163
|
-
(environment) => environment.setStore,
|
|
164
|
-
(environment) => environment.config,
|
|
165
|
-
(getCxf, setStore, { CXF_AD_STATUS }) =>
|
|
166
|
-
() => {
|
|
167
|
-
const cxf = getCxf()
|
|
168
|
-
cxf.on(CXF_AD_STATUS, ({ areBannersAvailable, bannersDetails }: Record<string, any>) => {
|
|
169
|
-
setStore({
|
|
170
|
-
adStatus: {
|
|
171
|
-
areBannersAvailable,
|
|
172
|
-
bannersDetails,
|
|
173
|
-
},
|
|
174
|
-
})
|
|
175
|
-
})
|
|
176
|
-
}
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
/*
|
|
180
|
-
Use a dedicated config variant on temp servers
|
|
181
|
-
*/
|
|
182
|
-
|
|
183
|
-
export const tempServerContextReducer: DIReader<SubscribeToCxf> = inject(
|
|
184
|
-
(environment) => environment.getCxf,
|
|
185
|
-
(environment) => environment.getStore,
|
|
186
|
-
(environment) => environment.setStore,
|
|
187
|
-
(environment) => environment.preResolveConfig,
|
|
188
|
-
(getCxf, getStore, setStore, preResolveConfig) => () => {
|
|
189
|
-
const cxf = getCxf()
|
|
190
|
-
cxf.on(WebshopEvents.CXF_JOIN_TEMP_SERVER, (isTemp: 0 | 1) => {
|
|
191
|
-
const store = getStore()
|
|
192
|
-
setStore({
|
|
193
|
-
isTempServer: Boolean(isTemp),
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
// ensure suffix is not already set by the environment, e.g. BFW or MS integration
|
|
197
|
-
// TODO: fully migrate client detection into `cxf-webshop`
|
|
198
|
-
if (store.customizationSuffix === '' || store.customizationSuffix === 'temp') {
|
|
199
|
-
setStore({
|
|
200
|
-
customizationSuffix: isTemp ? 'temp' : '',
|
|
201
|
-
})
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
preResolveConfig()
|
|
205
|
-
})
|
|
206
|
-
}
|
|
207
|
-
)
|
package/src_old/helpers.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import debug from 'debug'
|
|
3
|
-
import { inject } from 'readuz'
|
|
4
|
-
import { v4 as uuidv4 } from 'uuid'
|
|
5
|
-
import { DIReader, IDictionary } from './common'
|
|
6
|
-
import { parentDomain, timeout } from './utils'
|
|
7
|
-
import { ArgumentNullError } from './ArgumentNullError'
|
|
8
|
-
import { encodePing } from './ping'
|
|
9
|
-
import { IStore } from './store'
|
|
10
|
-
import { ICXF } from './cxf'
|
|
11
|
-
|
|
12
|
-
export function formatQueryString(object: IDictionary<string | number | undefined | null>) {
|
|
13
|
-
return Object.entries(object)
|
|
14
|
-
.filter(([key, value]) => value !== null && value !== undefined)
|
|
15
|
-
.map(([key, value]) => `${key}=${encodeURIComponent(value as string)}`)
|
|
16
|
-
.join('&')
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const getTokenAndLanguage = (store: IStore) => {
|
|
20
|
-
const { playerId, token, zoneId, language } = store
|
|
21
|
-
if (!playerId) {
|
|
22
|
-
throw new ArgumentNullError('playerId', playerId)
|
|
23
|
-
}
|
|
24
|
-
return {
|
|
25
|
-
token,
|
|
26
|
-
zoneId,
|
|
27
|
-
locale: language,
|
|
28
|
-
ping: encodePing({ ...store, playerId }),
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface IProvider<T> {
|
|
33
|
-
get: () => T | undefined
|
|
34
|
-
set: (value: T) => void
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export const getCxf = (cxfProvider: IProvider<ICXF>) => {
|
|
38
|
-
const cxf = cxfProvider.get()
|
|
39
|
-
if (!cxf) {
|
|
40
|
-
throw new ArgumentNullError('cxf', cxf)
|
|
41
|
-
}
|
|
42
|
-
return cxf
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export type GetPing = () => string
|
|
46
|
-
export const getPing: DIReader<GetPing> = inject(
|
|
47
|
-
(environment) => environment.getStore,
|
|
48
|
-
(getStore) => () => {
|
|
49
|
-
const store = getStore()
|
|
50
|
-
const { playerId } = store
|
|
51
|
-
if (!playerId) {
|
|
52
|
-
throw new ArgumentNullError('playerId', playerId)
|
|
53
|
-
}
|
|
54
|
-
return encodePing({ ...store, playerId })
|
|
55
|
-
}
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
export const entityProvider = <T>(initial?: T): IProvider<T> => {
|
|
59
|
-
let element = initial
|
|
60
|
-
return {
|
|
61
|
-
get: () => element,
|
|
62
|
-
set: (value) => {
|
|
63
|
-
element = value
|
|
64
|
-
},
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export type TryCatch = {
|
|
69
|
-
<R>(function_: () => R): () => R
|
|
70
|
-
<P1, R>(function_: (p1: P1) => R): (p1: P1) => R
|
|
71
|
-
<P1, P2, R>(function_: (p1: P1, p2: P2) => R): (p1: P1, p2: P2) => R
|
|
72
|
-
<P1, P2, P3, R>(function_: (p1: P1, p2: P2, p3: P3) => R): (p1: P1, p2: P2, p3: P3) => R
|
|
73
|
-
}
|
|
74
|
-
export const tryCatch: DIReader<TryCatch> = inject(
|
|
75
|
-
(environment) => environment.logError,
|
|
76
|
-
(environment) => environment.throwCxfError,
|
|
77
|
-
(logError_, throwAnError) =>
|
|
78
|
-
(function_: any) =>
|
|
79
|
-
(...arguments_: any[]) => {
|
|
80
|
-
try {
|
|
81
|
-
function_(...arguments_)
|
|
82
|
-
} catch (error) {
|
|
83
|
-
logError_(error)
|
|
84
|
-
throwAnError(error as Error)
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
export type ThrowCxfError = (e: Error) => void
|
|
90
|
-
export const throwCxfError: DIReader<ThrowCxfError> = inject(
|
|
91
|
-
(environment) => environment.config,
|
|
92
|
-
(environment) => environment.cxfProvider,
|
|
93
|
-
({ CXF_ERROR }, cxfProvider) =>
|
|
94
|
-
(e) => {
|
|
95
|
-
const cxf = getCxf(cxfProvider)
|
|
96
|
-
cxf.emit(CXF_ERROR, e)
|
|
97
|
-
}
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
export const isArgumentNullError = (e: Error): e is ArgumentNullError => e.name === 'ArgumentNullError'
|
|
101
|
-
|
|
102
|
-
export type LoadCxf = (...arguments_: any[]) => Promise<ICXF>
|
|
103
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
104
|
-
export const loadCxf = timeout(() => require('@goodgamestudios/cxf-ready') as Promise<ICXF>, 10_000)
|
|
105
|
-
|
|
106
|
-
/*
|
|
107
|
-
* To show CXF-WEBSHOP debug messages just run in a browser console
|
|
108
|
-
* localStorage.debug = 'CXF-WEBSHOP:*'
|
|
109
|
-
*/
|
|
110
|
-
const logger = debug('CXF-WEBSHOP')
|
|
111
|
-
export type Log = (...arguments_: any[]) => void
|
|
112
|
-
export const log: Log = (argument0: any, ...rest: any[]) => logger(argument0, ...rest)
|
|
113
|
-
|
|
114
|
-
export type LogError = (...arguments_: any[]) => void
|
|
115
|
-
export const logError: LogError = (...arguments_: any[]) =>
|
|
116
|
-
// tslint:disable-next-line:no-console
|
|
117
|
-
console.error('%c CXF-WEBSHOP:', 'background: #ff0000; color: #fff', ...arguments_)
|
|
118
|
-
|
|
119
|
-
export const createSessionId = () => uuidv4()
|
|
120
|
-
|
|
121
|
-
export type GetDomain = (referrer: string) => string | undefined
|
|
122
|
-
export const getDomain: DIReader<GetDomain> = inject(
|
|
123
|
-
(environment) => environment.log,
|
|
124
|
-
() => (referrer) => {
|
|
125
|
-
return parentDomain(referrer)
|
|
126
|
-
}
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
export type GGSGetQueryParams = () => string
|
|
130
|
-
export const ggsGetQueryParams: DIReader<GGSGetQueryParams> = inject(
|
|
131
|
-
(environment) => environment.log,
|
|
132
|
-
(nothing) => () => {
|
|
133
|
-
return ggsGetQueryParameters()
|
|
134
|
-
}
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
export type GGSGetReferrerValue = () => string
|
|
138
|
-
export const ggsGetReferrerValue: DIReader<GGSGetReferrerValue> = inject(
|
|
139
|
-
(environment) => environment.log,
|
|
140
|
-
(nothing) => () => {
|
|
141
|
-
return ggsGetReferrer()
|
|
142
|
-
}
|
|
143
|
-
)
|
package/src_old/index.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { createEnv as createEnvironment } from './env'
|
|
2
|
-
import { app } from './app'
|
|
3
|
-
import { just } from 'readuz'
|
|
4
|
-
import { entityProvider, log } from './helpers'
|
|
5
|
-
import { defaultStore } from './store'
|
|
6
|
-
import { createConfig } from './config'
|
|
7
|
-
import {
|
|
8
|
-
createCxfReducers,
|
|
9
|
-
nativeSubscriptionEnableReducer,
|
|
10
|
-
setCustomizationSuffixReducer,
|
|
11
|
-
receiveAdStatusReducer,
|
|
12
|
-
tempServerContextReducer,
|
|
13
|
-
} from './handlers/reducers'
|
|
14
|
-
import { ICXF } from './cxf'
|
|
15
|
-
|
|
16
|
-
if (localStorage.getItem('cxf_canvas') === 'enabled') {
|
|
17
|
-
log('Skip cxf-webshop loading...')
|
|
18
|
-
} else {
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires, unicorn/prefer-top-level-await
|
|
20
|
-
require('@goodgamestudios/cxf-ready').then((cxf: ICXF) => {
|
|
21
|
-
app(
|
|
22
|
-
createEnvironment({
|
|
23
|
-
config: just(createConfig(cxf.gameId)),
|
|
24
|
-
cxfProvider: just(entityProvider(cxf)),
|
|
25
|
-
store: just(entityProvider(defaultStore(cxf))),
|
|
26
|
-
subscribeToCxf: createCxfReducers({
|
|
27
|
-
receiveAdStatus: receiveAdStatusReducer,
|
|
28
|
-
tempServerContext: tempServerContextReducer,
|
|
29
|
-
nativeSubscription: nativeSubscriptionEnableReducer,
|
|
30
|
-
setCustomizationSuffix: setCustomizationSuffixReducer,
|
|
31
|
-
}),
|
|
32
|
-
})
|
|
33
|
-
)
|
|
34
|
-
})
|
|
35
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { IShopMessageBus } from './IShopMessageBus'
|
|
2
|
-
|
|
3
|
-
export class ShopMessageBus implements IShopMessageBus {
|
|
4
|
-
public post(message: any) {
|
|
5
|
-
const element = document.querySelector('#dialog') as HTMLIFrameElement
|
|
6
|
-
if (element && element.tagName.toLocaleLowerCase() === 'iframe') {
|
|
7
|
-
element.contentWindow?.postMessage(message, '*')
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { IShopMessageBus } from './IShopMessageBus'
|
|
2
|
-
|
|
3
|
-
export class TestShopMessageBus implements IShopMessageBus {
|
|
4
|
-
public post(message: any) {
|
|
5
|
-
/* eslint-disable-next-line prettier/prettier */
|
|
6
|
-
(window as any).dialogPostMessage = JSON.stringify(message)
|
|
7
|
-
}
|
|
8
|
-
}
|
package/src_old/ping.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface PingProperties {
|
|
2
|
-
gameId: string
|
|
3
|
-
networkId: string
|
|
4
|
-
instanceId: string
|
|
5
|
-
playerId: string
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function decodePing(value: string): PingProperties {
|
|
9
|
-
const [gameId, networkId, instanceId, playerId] = value.split('-')
|
|
10
|
-
return { gameId, networkId, instanceId, playerId }
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function encodePing({ gameId, networkId, instanceId, playerId }: PingProperties): string {
|
|
14
|
-
return [gameId, networkId, instanceId, playerId].join('-')
|
|
15
|
-
}
|