@adhese/sdk 1.11.6 → 1.11.7
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/CHANGELOG.md +6 -0
- package/dist/cjs/package.json.cjs +1 -1
- package/dist/cjs/requestAds/requestAds.cjs +18 -13
- package/dist/cjs/requestAds/requestAds.cjs.map +1 -1
- package/dist/package.json.js +1 -1
- package/dist/requestAds/requestAds.js +18 -13
- package/dist/requestAds/requestAds.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const name = "@adhese/sdk";
|
|
4
|
-
const version = "1.11.
|
|
4
|
+
const version = "1.11.7";
|
|
5
5
|
exports.name = name;
|
|
6
6
|
exports.version = version;
|
|
7
7
|
//# sourceMappingURL=package.json.cjs.map
|
|
@@ -9,18 +9,23 @@ const runRequestAdsBatch = sdkShared.debounce(
|
|
|
9
9
|
async (context) => {
|
|
10
10
|
if (batch.size === 0)
|
|
11
11
|
return [];
|
|
12
|
-
const
|
|
13
|
-
slots: Array.from(batch.values()).map(({ options }) => options.slot),
|
|
14
|
-
context
|
|
15
|
-
});
|
|
16
|
-
for (const { options, resolve } of batch.values()) {
|
|
17
|
-
const ad = ads.find(({ slotName }) => slotName === options.slot.name);
|
|
18
|
-
if (ad)
|
|
19
|
-
resolve(ad);
|
|
20
|
-
else resolve(null);
|
|
21
|
-
}
|
|
12
|
+
const entries = Array.from(batch.values());
|
|
22
13
|
batch.clear();
|
|
23
|
-
|
|
14
|
+
try {
|
|
15
|
+
const ads = await requestAds({
|
|
16
|
+
slots: entries.map(({ options }) => options.slot),
|
|
17
|
+
context
|
|
18
|
+
});
|
|
19
|
+
for (const { options, resolve } of entries) {
|
|
20
|
+
const ad = ads.find(({ slotName }) => slotName === options.slot.name);
|
|
21
|
+
resolve(ad ?? null);
|
|
22
|
+
}
|
|
23
|
+
return ads;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
for (const { reject } of entries)
|
|
26
|
+
reject(error);
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
24
29
|
},
|
|
25
30
|
{
|
|
26
31
|
waitMs: 200,
|
|
@@ -28,8 +33,8 @@ const runRequestAdsBatch = sdkShared.debounce(
|
|
|
28
33
|
}
|
|
29
34
|
);
|
|
30
35
|
async function requestAd(options) {
|
|
31
|
-
const promise = new Promise((resolve) => {
|
|
32
|
-
batch.set(options.slot.name, { options, resolve });
|
|
36
|
+
const promise = new Promise((resolve, reject) => {
|
|
37
|
+
batch.set(options.slot.name, { options, resolve, reject });
|
|
33
38
|
});
|
|
34
39
|
await runRequestAdsBatch.call(options.context);
|
|
35
40
|
return promise;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestAds.cjs","sources":["../../../src/requestAds/requestAds.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseAd } from './requestAds.schema';\nimport { debounce } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { requestPreviews } from './requestAds.preview';\nimport { requestWithGet, requestWithPost } from './requestAds.utils';\n\nexport type AdRequestOptions = {\n /**\n * Slot you want to fetch the ad for\n */\n slot: {\n name: string;\n parameters: Map<string, ReadonlyArray<string> | string>;\n };\n context: AdheseContext;\n};\n\nexport type AdMultiRequestOptions = Omit<AdRequestOptions, 'slot'> & {\n slots: ReadonlyArray<AdRequestOptions['slot']>;\n};\n\nconst batch = new Map<\n string,\n {\n options: AdRequestOptions;\n resolve(ad: AdheseAd | null): void;\n }\n>();\n\n/**\n * Debounced function to request ads in batches. This function is debounced to prevent multiple requests for the same ad.\n */\nconst runRequestAdsBatch = debounce(\n async (context: AdheseContext) => {\n if (batch.size === 0)\n return [];\n\n const ads = await requestAds({\n
|
|
1
|
+
{"version":3,"file":"requestAds.cjs","sources":["../../../src/requestAds/requestAds.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseAd } from './requestAds.schema';\nimport { debounce } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { requestPreviews } from './requestAds.preview';\nimport { requestWithGet, requestWithPost } from './requestAds.utils';\n\nexport type AdRequestOptions = {\n /**\n * Slot you want to fetch the ad for\n */\n slot: {\n name: string;\n parameters: Map<string, ReadonlyArray<string> | string>;\n };\n context: AdheseContext;\n};\n\nexport type AdMultiRequestOptions = Omit<AdRequestOptions, 'slot'> & {\n slots: ReadonlyArray<AdRequestOptions['slot']>;\n};\n\nconst batch = new Map<\n string,\n {\n options: AdRequestOptions;\n resolve(ad: AdheseAd | null): void;\n reject(error: unknown): void;\n }\n>();\n\n/**\n * Debounced function to request ads in batches. This function is debounced to prevent multiple requests for the same ad.\n */\nconst runRequestAdsBatch = debounce(\n async (context: AdheseContext) => {\n if (batch.size === 0)\n return [];\n\n const entries = Array.from(batch.values());\n batch.clear();\n\n try {\n const ads = await requestAds({\n slots: entries.map(({ options }) => options.slot),\n context,\n });\n\n for (const { options, resolve } of entries) {\n const ad = ads.find(({ slotName }) => slotName === options.slot.name);\n resolve(ad ?? null);\n }\n\n return ads;\n }\n catch (error) {\n for (const { reject } of entries)\n reject(error);\n\n return [];\n }\n },\n {\n waitMs: 200,\n timing: 'trailing',\n },\n);\n\n/**\n * Request a single ad from the API. If you need to fetch multiple ads at once use the `requestAds` function.\n */\nexport async function requestAd(\n options: AdRequestOptions,\n): Promise<AdheseAd | null> {\n const promise = new Promise<AdheseAd | null>((resolve, reject) => {\n batch.set(options.slot.name, { options, resolve, reject });\n });\n\n await runRequestAdsBatch.call(options.context);\n\n return promise;\n}\n\n/**\n * Request multiple ads from the API. If you need to fetch a single ad use the `requestAd` function.\n */\nexport async function requestAds(\n requestOptions: AdMultiRequestOptions,\n): Promise<ReadonlyArray<AdheseAd>> {\n const options = await requestOptions.context.hooks.runOnRequest(\n requestOptions,\n );\n\n const { context } = options;\n\n try {\n context?.events?.requestAd.dispatch({\n ...options,\n context,\n });\n\n const [response, previews, parseResponse] = await Promise.all([\n context.options.requestType?.toUpperCase() === 'POST'\n ? requestWithPost(options)\n : requestWithGet(options),\n requestPreviews(options?.context?.options.previewHost),\n import('./requestAds.schema').then(module => module.parseResponse),\n ]);\n\n logger.debug('Received response', response);\n\n if (!response.ok) {\n throw new Error(\n `Failed to request ad: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = parseResponse((await response.json()) as unknown);\n logger.debug('Parsed ad', result);\n\n if (previews.length > 0) {\n logger.info(\n `Found ${previews.length} ${\n previews.length === 1 ? 'preview' : 'previews'\n }. Replacing ads in response with preview items`,\n previews,\n );\n }\n\n const matchedPreviews: Array<AdheseAd> = [];\n for (const [, value] of context.slots.entries()) {\n const ad = result.find(({ slotName }) => slotName === value.name);\n const partnerAd = previews.find(\n preview => preview.adType === value.format,\n );\n if (ad || partnerAd) {\n const baseAd = partnerAd ?? ad;\n matchedPreviews.push({\n ...baseAd,\n slotName: value.name,\n } as AdheseAd);\n }\n else {\n if (value.status === 'loading')\n value.processOnEmpty();\n }\n }\n\n if (matchedPreviews.length > 0)\n context.events?.previewReceived.dispatch(matchedPreviews);\n\n const mergedResult = await context.hooks.runOnResponse(matchedPreviews);\n\n context.events?.responseReceived.dispatch(mergedResult);\n\n return mergedResult;\n }\n catch (error) {\n logger.error(String(error));\n context?.events?.requestError.dispatch(error as Error);\n throw error;\n }\n}\n"],"names":["debounce","requestWithPost","requestWithGet","requestPreviews","module","logger"],"mappings":"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"}
|
package/dist/package.json.js
CHANGED
|
@@ -7,18 +7,23 @@ const runRequestAdsBatch = debounce(
|
|
|
7
7
|
async (context) => {
|
|
8
8
|
if (batch.size === 0)
|
|
9
9
|
return [];
|
|
10
|
-
const
|
|
11
|
-
slots: Array.from(batch.values()).map(({ options }) => options.slot),
|
|
12
|
-
context
|
|
13
|
-
});
|
|
14
|
-
for (const { options, resolve } of batch.values()) {
|
|
15
|
-
const ad = ads.find(({ slotName }) => slotName === options.slot.name);
|
|
16
|
-
if (ad)
|
|
17
|
-
resolve(ad);
|
|
18
|
-
else resolve(null);
|
|
19
|
-
}
|
|
10
|
+
const entries = Array.from(batch.values());
|
|
20
11
|
batch.clear();
|
|
21
|
-
|
|
12
|
+
try {
|
|
13
|
+
const ads = await requestAds({
|
|
14
|
+
slots: entries.map(({ options }) => options.slot),
|
|
15
|
+
context
|
|
16
|
+
});
|
|
17
|
+
for (const { options, resolve } of entries) {
|
|
18
|
+
const ad = ads.find(({ slotName }) => slotName === options.slot.name);
|
|
19
|
+
resolve(ad ?? null);
|
|
20
|
+
}
|
|
21
|
+
return ads;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
for (const { reject } of entries)
|
|
24
|
+
reject(error);
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
22
27
|
},
|
|
23
28
|
{
|
|
24
29
|
waitMs: 200,
|
|
@@ -26,8 +31,8 @@ const runRequestAdsBatch = debounce(
|
|
|
26
31
|
}
|
|
27
32
|
);
|
|
28
33
|
async function requestAd(options) {
|
|
29
|
-
const promise = new Promise((resolve) => {
|
|
30
|
-
batch.set(options.slot.name, { options, resolve });
|
|
34
|
+
const promise = new Promise((resolve, reject) => {
|
|
35
|
+
batch.set(options.slot.name, { options, resolve, reject });
|
|
31
36
|
});
|
|
32
37
|
await runRequestAdsBatch.call(options.context);
|
|
33
38
|
return promise;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestAds.js","sources":["../../src/requestAds/requestAds.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseAd } from './requestAds.schema';\nimport { debounce } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { requestPreviews } from './requestAds.preview';\nimport { requestWithGet, requestWithPost } from './requestAds.utils';\n\nexport type AdRequestOptions = {\n /**\n * Slot you want to fetch the ad for\n */\n slot: {\n name: string;\n parameters: Map<string, ReadonlyArray<string> | string>;\n };\n context: AdheseContext;\n};\n\nexport type AdMultiRequestOptions = Omit<AdRequestOptions, 'slot'> & {\n slots: ReadonlyArray<AdRequestOptions['slot']>;\n};\n\nconst batch = new Map<\n string,\n {\n options: AdRequestOptions;\n resolve(ad: AdheseAd | null): void;\n }\n>();\n\n/**\n * Debounced function to request ads in batches. This function is debounced to prevent multiple requests for the same ad.\n */\nconst runRequestAdsBatch = debounce(\n async (context: AdheseContext) => {\n if (batch.size === 0)\n return [];\n\n const ads = await requestAds({\n
|
|
1
|
+
{"version":3,"file":"requestAds.js","sources":["../../src/requestAds/requestAds.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseAd } from './requestAds.schema';\nimport { debounce } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { requestPreviews } from './requestAds.preview';\nimport { requestWithGet, requestWithPost } from './requestAds.utils';\n\nexport type AdRequestOptions = {\n /**\n * Slot you want to fetch the ad for\n */\n slot: {\n name: string;\n parameters: Map<string, ReadonlyArray<string> | string>;\n };\n context: AdheseContext;\n};\n\nexport type AdMultiRequestOptions = Omit<AdRequestOptions, 'slot'> & {\n slots: ReadonlyArray<AdRequestOptions['slot']>;\n};\n\nconst batch = new Map<\n string,\n {\n options: AdRequestOptions;\n resolve(ad: AdheseAd | null): void;\n reject(error: unknown): void;\n }\n>();\n\n/**\n * Debounced function to request ads in batches. This function is debounced to prevent multiple requests for the same ad.\n */\nconst runRequestAdsBatch = debounce(\n async (context: AdheseContext) => {\n if (batch.size === 0)\n return [];\n\n const entries = Array.from(batch.values());\n batch.clear();\n\n try {\n const ads = await requestAds({\n slots: entries.map(({ options }) => options.slot),\n context,\n });\n\n for (const { options, resolve } of entries) {\n const ad = ads.find(({ slotName }) => slotName === options.slot.name);\n resolve(ad ?? null);\n }\n\n return ads;\n }\n catch (error) {\n for (const { reject } of entries)\n reject(error);\n\n return [];\n }\n },\n {\n waitMs: 200,\n timing: 'trailing',\n },\n);\n\n/**\n * Request a single ad from the API. If you need to fetch multiple ads at once use the `requestAds` function.\n */\nexport async function requestAd(\n options: AdRequestOptions,\n): Promise<AdheseAd | null> {\n const promise = new Promise<AdheseAd | null>((resolve, reject) => {\n batch.set(options.slot.name, { options, resolve, reject });\n });\n\n await runRequestAdsBatch.call(options.context);\n\n return promise;\n}\n\n/**\n * Request multiple ads from the API. If you need to fetch a single ad use the `requestAd` function.\n */\nexport async function requestAds(\n requestOptions: AdMultiRequestOptions,\n): Promise<ReadonlyArray<AdheseAd>> {\n const options = await requestOptions.context.hooks.runOnRequest(\n requestOptions,\n );\n\n const { context } = options;\n\n try {\n context?.events?.requestAd.dispatch({\n ...options,\n context,\n });\n\n const [response, previews, parseResponse] = await Promise.all([\n context.options.requestType?.toUpperCase() === 'POST'\n ? requestWithPost(options)\n : requestWithGet(options),\n requestPreviews(options?.context?.options.previewHost),\n import('./requestAds.schema').then(module => module.parseResponse),\n ]);\n\n logger.debug('Received response', response);\n\n if (!response.ok) {\n throw new Error(\n `Failed to request ad: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = parseResponse((await response.json()) as unknown);\n logger.debug('Parsed ad', result);\n\n if (previews.length > 0) {\n logger.info(\n `Found ${previews.length} ${\n previews.length === 1 ? 'preview' : 'previews'\n }. Replacing ads in response with preview items`,\n previews,\n );\n }\n\n const matchedPreviews: Array<AdheseAd> = [];\n for (const [, value] of context.slots.entries()) {\n const ad = result.find(({ slotName }) => slotName === value.name);\n const partnerAd = previews.find(\n preview => preview.adType === value.format,\n );\n if (ad || partnerAd) {\n const baseAd = partnerAd ?? ad;\n matchedPreviews.push({\n ...baseAd,\n slotName: value.name,\n } as AdheseAd);\n }\n else {\n if (value.status === 'loading')\n value.processOnEmpty();\n }\n }\n\n if (matchedPreviews.length > 0)\n context.events?.previewReceived.dispatch(matchedPreviews);\n\n const mergedResult = await context.hooks.runOnResponse(matchedPreviews);\n\n context.events?.responseReceived.dispatch(mergedResult);\n\n return mergedResult;\n }\n catch (error) {\n logger.error(String(error));\n context?.events?.requestError.dispatch(error as Error);\n throw error;\n }\n}\n"],"names":[],"mappings":";;;;AAsBA,MAAM,4BAAY,IAOhB;AAKF,MAAM,qBAAqB;AAAA,EACzB,OAAO,YAA2B;AAChC,QAAI,MAAM,SAAS;AACjB,aAAO,CAAC;AAEV,UAAM,UAAU,MAAM,KAAK,MAAM,QAAQ;AACzC,UAAM,MAAM;AAER,QAAA;AACI,YAAA,MAAM,MAAM,WAAW;AAAA,QAC3B,OAAO,QAAQ,IAAI,CAAC,EAAE,QAAQ,MAAM,QAAQ,IAAI;AAAA,QAChD;AAAA,MAAA,CACD;AAED,iBAAW,EAAE,SAAS,QAAQ,KAAK,SAAS;AACpC,cAAA,KAAK,IAAI,KAAK,CAAC,EAAE,SAAe,MAAA,aAAa,QAAQ,KAAK,IAAI;AACpE,gBAAQ,MAAM,IAAI;AAAA,MAAA;AAGb,aAAA;AAAA,aAEF,OAAO;AACD,iBAAA,EAAE,YAAY;AACvB,eAAO,KAAK;AAEd,aAAO,CAAC;AAAA,IAAA;AAAA,EAEZ;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,EAAA;AAEZ;AAKA,eAAsB,UACpB,SAC0B;AAC1B,QAAM,UAAU,IAAI,QAAyB,CAAC,SAAS,WAAW;AAC1D,UAAA,IAAI,QAAQ,KAAK,MAAM,EAAE,SAAS,SAAS,QAAQ;AAAA,EAAA,CAC1D;AAEK,QAAA,mBAAmB,KAAK,QAAQ,OAAO;AAEtC,SAAA;AACT;AAKA,eAAsB,WACpB,gBACkC;;AAClC,QAAM,UAAU,MAAM,eAAe,QAAQ,MAAM;AAAA,IACjD;AAAA,EACF;AAEM,QAAA,EAAE,YAAY;AAEhB,MAAA;AACO,6CAAA,WAAA,mBAAQ,UAAU,SAAS;AAAA,MAClC,GAAG;AAAA,MACH;AAAA,IAAA;AAGF,UAAM,CAAC,UAAU,UAAU,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC5D,aAAQ,QAAQ,gBAAhB,mBAA6B,mBAAkB,SAC3C,gBAAgB,OAAO,IACvB,eAAe,OAAO;AAAA,MAC1B,iBAAgB,wCAAS,YAAT,mBAAkB,QAAQ,WAAW;AAAA,MACrD,OAAO,wBAAqB,EAAE,KAAK,CAAA,WAAU,OAAO,aAAa;AAAA,IAAA,CAClE;AAEM,WAAA,MAAM,qBAAqB,QAAQ;AAEtC,QAAA,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI;AAAA,QACR,yBAAyB,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,MACjE;AAAA,IAAA;AAGF,UAAM,SAAS,cAAe,MAAM,SAAS,MAAkB;AACxD,WAAA,MAAM,aAAa,MAAM;AAE5B,QAAA,SAAS,SAAS,GAAG;AAChB,aAAA;AAAA,QACL,SAAS,SAAS,MAAM,IACtB,SAAS,WAAW,IAAI,YAAY,UACtC;AAAA,QACA;AAAA,MACF;AAAA,IAAA;AAGF,UAAM,kBAAmC,CAAC;AAC1C,eAAW,CAAG,EAAA,KAAK,KAAK,QAAQ,MAAM,WAAW;AACzC,YAAA,KAAK,OAAO,KAAK,CAAC,EAAE,eAAe,aAAa,MAAM,IAAI;AAChE,YAAM,YAAY,SAAS;AAAA,QACzB,CAAA,YAAW,QAAQ,WAAW,MAAM;AAAA,MACtC;AACA,UAAI,MAAM,WAAW;AACnB,cAAM,SAAS,aAAa;AAC5B,wBAAgB,KAAK;AAAA,UACnB,GAAG;AAAA,UACH,UAAU,MAAM;AAAA,QAAA,CACL;AAAA,MAAA,OAEV;AACH,YAAI,MAAM,WAAW;AACnB,gBAAM,eAAe;AAAA,MAAA;AAAA,IACzB;AAGF,QAAI,gBAAgB,SAAS;AACnB,oBAAA,WAAA,mBAAQ,gBAAgB,SAAS;AAE3C,UAAM,eAAe,MAAM,QAAQ,MAAM,cAAc,eAAe;AAE9D,kBAAA,WAAA,mBAAQ,iBAAiB,SAAS;AAEnC,WAAA;AAAA,WAEF,OAAO;AACL,WAAA,MAAM,OAAO,KAAK,CAAC;AACjB,6CAAA,WAAA,mBAAQ,aAAa,SAAS;AACjC,UAAA;AAAA,EAAA;AAEV;"}
|