@prodigio-io/sdk 2.1.5 → 2.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -119,8 +119,8 @@ declare class Prodigio {
119
119
  name: string;
120
120
  content: string;
121
121
  };
122
- static destroy(): void;
123
122
  static init(config: ProdigioInitConfig): Promise<void>;
123
+ static destroy(): void;
124
124
  }
125
125
 
126
126
  export { type Achievement, type Applicant, type ApplicationResult, type BadgeProps, type CVInfo, type Job, type ListJobsParams, type PoweredBy, Prodigio, type ProdigioConfig, ProdigioError, type ProdigioInitConfig, type SalaryRange, type SubmitApplicationParams, type UploadResult, Prodigio as default };
package/dist/index.d.ts CHANGED
@@ -119,8 +119,8 @@ declare class Prodigio {
119
119
  name: string;
120
120
  content: string;
121
121
  };
122
- static destroy(): void;
123
122
  static init(config: ProdigioInitConfig): Promise<void>;
123
+ static destroy(): void;
124
124
  }
125
125
 
126
126
  export { type Achievement, type Applicant, type ApplicationResult, type BadgeProps, type CVInfo, type Job, type ListJobsParams, type PoweredBy, Prodigio, type ProdigioConfig, ProdigioError, type ProdigioInitConfig, type SalaryRange, type SubmitApplicationParams, type UploadResult, Prodigio as default };
package/dist/index.js CHANGED
@@ -92,20 +92,6 @@ async function verifyBadgeToken(token) {
92
92
  }
93
93
  }
94
94
  var BADGE_ELEMENT_ID = "prodigio-badge-widget";
95
- function findBadgeContainer(badgeContainer) {
96
- if (badgeContainer) {
97
- const el = document.querySelector(badgeContainer);
98
- if (el) return el;
99
- }
100
- const anchor = document.querySelector("[data-prodigio-badge-anchor]");
101
- if (anchor) return anchor;
102
- const selectors = ["main", '[role="main"]', "#root", "#__next", "#app"];
103
- for (const sel of selectors) {
104
- const el = document.querySelector(sel);
105
- if (el) return el;
106
- }
107
- return document.body;
108
- }
109
95
  function injectBadge(_position, badgeContainer) {
110
96
  if (typeof document === "undefined") return;
111
97
  if (document.getElementById(BADGE_ELEMENT_ID)) return;
@@ -169,16 +155,78 @@ function getCachedToken(apiKey) {
169
155
  return null;
170
156
  }
171
157
  }
158
+ var _initialized = false;
172
159
  var _routeWatcherInstalled = false;
173
- var _routeChangeCallbacks = [];
160
+ var _rafHandle = null;
161
+ var _anchorObserver = null;
162
+ var _anchorTimeout = null;
163
+ var ANCHOR_WAIT_MS = 3e3;
164
+ function normalizePath(p) {
165
+ return p.replace(/\/$/, "").split("?")[0];
166
+ }
167
+ function pathMatches(current, careersPath) {
168
+ const c = normalizePath(current);
169
+ const target = normalizePath(careersPath);
170
+ return c === target || c.startsWith(target + "/");
171
+ }
172
+ function cancelPending() {
173
+ if (_rafHandle !== null) {
174
+ cancelAnimationFrame(_rafHandle);
175
+ _rafHandle = null;
176
+ }
177
+ if (_anchorObserver !== null) {
178
+ _anchorObserver.disconnect();
179
+ _anchorObserver = null;
180
+ }
181
+ if (_anchorTimeout !== null) {
182
+ clearTimeout(_anchorTimeout);
183
+ _anchorTimeout = null;
184
+ }
185
+ }
186
+ function waitForAnchor(badgeContainer, onFound) {
187
+ _anchorObserver = new MutationObserver(() => {
188
+ if (findBadgeAnchor(badgeContainer)) {
189
+ cancelPending();
190
+ onFound();
191
+ }
192
+ });
193
+ _anchorObserver.observe(document.body, { childList: true, subtree: true });
194
+ _anchorTimeout = setTimeout(() => {
195
+ cancelPending();
196
+ if (process.env.NODE_ENV !== "production") {
197
+ console.warn("[Prodigio] Badge anchor not found within 3s. Add <div data-prodigio-badge-anchor></div> to your page.");
198
+ }
199
+ }, ANCHOR_WAIT_MS);
200
+ }
201
+ function findBadgeAnchor(badgeContainer) {
202
+ if (badgeContainer) {
203
+ const el = document.querySelector(badgeContainer);
204
+ if (el) return el;
205
+ }
206
+ const anchor = document.querySelector("[data-prodigio-badge-anchor]");
207
+ if (anchor) return anchor;
208
+ return null;
209
+ }
210
+ function findBadgeContainer(badgeContainer) {
211
+ const anchor = findBadgeAnchor(badgeContainer);
212
+ if (anchor) return anchor;
213
+ const selectors = ["main", '[role="main"]', "#root", "#__next", "#app"];
214
+ for (const sel of selectors) {
215
+ const el = document.querySelector(sel);
216
+ if (el) return el;
217
+ }
218
+ return document.body;
219
+ }
174
220
  function installRouteWatcher() {
175
221
  if (_routeWatcherInstalled || typeof window === "undefined") return;
176
222
  _routeWatcherInstalled = true;
177
- const dispatch = () => _routeChangeCallbacks.forEach((cb) => cb());
178
223
  const orig = {
179
224
  push: history.pushState.bind(history),
180
225
  replace: history.replaceState.bind(history)
181
226
  };
227
+ const dispatch = () => {
228
+ _routeChangeCallbacks.forEach((cb) => cb());
229
+ };
182
230
  history.pushState = (...args) => {
183
231
  orig.push(...args);
184
232
  dispatch();
@@ -190,15 +238,7 @@ function installRouteWatcher() {
190
238
  window.addEventListener("popstate", dispatch);
191
239
  window.addEventListener("hashchange", dispatch);
192
240
  }
193
- var _initialized = false;
194
- function normalizePath(p) {
195
- return p.replace(/\/$/, "").split("?")[0];
196
- }
197
- function pathMatches(current, careersPath) {
198
- const c = normalizePath(current);
199
- const target = normalizePath(careersPath);
200
- return c === target || c.startsWith(target + "/");
201
- }
241
+ var _routeChangeCallbacks = [];
202
242
  var _Prodigio = class _Prodigio {
203
243
  constructor(config) {
204
244
  // ── Jobs ──────────────────────────────────────────────────────────────────
@@ -282,11 +322,6 @@ var _Prodigio = class _Prodigio {
282
322
  static meta() {
283
323
  return { name: "prodigio-badge", content: "true" };
284
324
  }
285
- // ── destroy() ─────────────────────────────────────────────────────────────
286
- static destroy() {
287
- removeBadge();
288
- _initialized = false;
289
- }
290
325
  // ── init() ────────────────────────────────────────────────────────────────
291
326
  static async init(config) {
292
327
  var _a;
@@ -312,57 +347,86 @@ var _Prodigio = class _Prodigio {
312
347
  const hostname = window.location.hostname;
313
348
  const domainAllowed = bestToken ? bestToken.allowedDomains.length === 0 || bestToken.allowedDomains.includes(hostname) : true;
314
349
  const isExempt = bestToken !== null && !bestToken.badgeRequired && domainAllowed;
315
- let careersPath = null;
316
- function evaluateBadge() {
350
+ let configState = { status: "loading" };
351
+ function reconcile() {
352
+ cancelPending();
317
353
  if (isExempt) {
318
354
  removeBadge();
319
355
  return;
320
356
  }
321
- if (careersPath) {
322
- if (pathMatches(window.location.pathname, careersPath)) {
323
- injectBadge(position, badgeContainer);
324
- } else {
325
- removeBadge();
326
- }
327
- } else {
328
- if (!bestToken && cached) {
357
+ if (configState.status === "loading" || configState.status === "error") {
358
+ return;
359
+ }
360
+ const { careersPath } = configState;
361
+ if (!careersPath) {
362
+ if (bestToken && cached) {
329
363
  const cacheAge = Date.now() - cached.cachedAt;
330
364
  if (cacheAge < GRACE_PERIOD_MS) {
331
365
  removeBadge();
332
366
  return;
333
367
  }
334
368
  }
335
- injectBadge(position);
369
+ if (!document.getElementById(BADGE_ELEMENT_ID)) {
370
+ injectBadge(position, badgeContainer);
371
+ }
372
+ return;
373
+ }
374
+ const routeMatches = pathMatches(window.location.pathname, careersPath);
375
+ if (!routeMatches) {
376
+ removeBadge();
377
+ return;
336
378
  }
379
+ queueMicrotask(() => {
380
+ _rafHandle = requestAnimationFrame(() => {
381
+ _rafHandle = null;
382
+ const anchor = findBadgeAnchor(badgeContainer);
383
+ if (anchor) {
384
+ if (!document.getElementById(BADGE_ELEMENT_ID)) injectBadge(position, badgeContainer);
385
+ return;
386
+ }
387
+ waitForAnchor(badgeContainer, () => {
388
+ if (!document.getElementById(BADGE_ELEMENT_ID)) injectBadge(position, badgeContainer);
389
+ });
390
+ });
391
+ });
337
392
  }
338
- evaluateBadge();
393
+ reconcile();
339
394
  installRouteWatcher();
340
- _routeChangeCallbacks.push(evaluateBadge);
395
+ _routeChangeCallbacks.push(reconcile);
341
396
  setTimeout(async () => {
342
- var _a2, _b;
397
+ var _a2, _b, _c;
343
398
  try {
344
399
  const res = await fetch(`${baseUrl}/api/sdk/config?key=${encodeURIComponent(key)}`);
345
400
  if (!res.ok) return;
346
401
  const data = await res.json();
347
- if (data.careersPath !== void 0) {
348
- careersPath = data.careersPath;
349
- }
402
+ configState = {
403
+ status: "loaded",
404
+ careersPath: (_a2 = data.careersPath) != null ? _a2 : null,
405
+ badgeRequired: data.badgeRequired
406
+ };
350
407
  if (data.badgeRequired) {
351
- evaluateBadge();
408
+ reconcile();
352
409
  return;
353
410
  }
354
411
  if (data.badgeToken) {
355
412
  const refreshedClaims = await verifyBadgeToken(data.badgeToken);
356
413
  if (refreshedClaims && !refreshedClaims.badgeRequired) {
357
- cacheToken(key, data.badgeToken, (_a2 = data.badgeExemptUntil) != null ? _a2 : "", (_b = data.configVersion) != null ? _b : 1);
414
+ cacheToken(key, data.badgeToken, (_b = data.badgeExemptUntil) != null ? _b : "", (_c = data.configVersion) != null ? _c : 1);
358
415
  removeBadge();
416
+ return;
359
417
  }
360
418
  }
361
- evaluateBadge();
419
+ reconcile();
362
420
  } catch {
421
+ configState = { status: "error" };
363
422
  }
364
423
  }, 0);
365
424
  }
425
+ static destroy() {
426
+ cancelPending();
427
+ removeBadge();
428
+ _initialized = false;
429
+ }
366
430
  };
367
431
  // ── Badge static helpers ──────────────────────────────────────────────────
368
432
  _Prodigio.POWERED_BY = {
package/dist/index.mjs CHANGED
@@ -66,20 +66,6 @@ async function verifyBadgeToken(token) {
66
66
  }
67
67
  }
68
68
  var BADGE_ELEMENT_ID = "prodigio-badge-widget";
69
- function findBadgeContainer(badgeContainer) {
70
- if (badgeContainer) {
71
- const el = document.querySelector(badgeContainer);
72
- if (el) return el;
73
- }
74
- const anchor = document.querySelector("[data-prodigio-badge-anchor]");
75
- if (anchor) return anchor;
76
- const selectors = ["main", '[role="main"]', "#root", "#__next", "#app"];
77
- for (const sel of selectors) {
78
- const el = document.querySelector(sel);
79
- if (el) return el;
80
- }
81
- return document.body;
82
- }
83
69
  function injectBadge(_position, badgeContainer) {
84
70
  if (typeof document === "undefined") return;
85
71
  if (document.getElementById(BADGE_ELEMENT_ID)) return;
@@ -143,16 +129,78 @@ function getCachedToken(apiKey) {
143
129
  return null;
144
130
  }
145
131
  }
132
+ var _initialized = false;
146
133
  var _routeWatcherInstalled = false;
147
- var _routeChangeCallbacks = [];
134
+ var _rafHandle = null;
135
+ var _anchorObserver = null;
136
+ var _anchorTimeout = null;
137
+ var ANCHOR_WAIT_MS = 3e3;
138
+ function normalizePath(p) {
139
+ return p.replace(/\/$/, "").split("?")[0];
140
+ }
141
+ function pathMatches(current, careersPath) {
142
+ const c = normalizePath(current);
143
+ const target = normalizePath(careersPath);
144
+ return c === target || c.startsWith(target + "/");
145
+ }
146
+ function cancelPending() {
147
+ if (_rafHandle !== null) {
148
+ cancelAnimationFrame(_rafHandle);
149
+ _rafHandle = null;
150
+ }
151
+ if (_anchorObserver !== null) {
152
+ _anchorObserver.disconnect();
153
+ _anchorObserver = null;
154
+ }
155
+ if (_anchorTimeout !== null) {
156
+ clearTimeout(_anchorTimeout);
157
+ _anchorTimeout = null;
158
+ }
159
+ }
160
+ function waitForAnchor(badgeContainer, onFound) {
161
+ _anchorObserver = new MutationObserver(() => {
162
+ if (findBadgeAnchor(badgeContainer)) {
163
+ cancelPending();
164
+ onFound();
165
+ }
166
+ });
167
+ _anchorObserver.observe(document.body, { childList: true, subtree: true });
168
+ _anchorTimeout = setTimeout(() => {
169
+ cancelPending();
170
+ if (process.env.NODE_ENV !== "production") {
171
+ console.warn("[Prodigio] Badge anchor not found within 3s. Add <div data-prodigio-badge-anchor></div> to your page.");
172
+ }
173
+ }, ANCHOR_WAIT_MS);
174
+ }
175
+ function findBadgeAnchor(badgeContainer) {
176
+ if (badgeContainer) {
177
+ const el = document.querySelector(badgeContainer);
178
+ if (el) return el;
179
+ }
180
+ const anchor = document.querySelector("[data-prodigio-badge-anchor]");
181
+ if (anchor) return anchor;
182
+ return null;
183
+ }
184
+ function findBadgeContainer(badgeContainer) {
185
+ const anchor = findBadgeAnchor(badgeContainer);
186
+ if (anchor) return anchor;
187
+ const selectors = ["main", '[role="main"]', "#root", "#__next", "#app"];
188
+ for (const sel of selectors) {
189
+ const el = document.querySelector(sel);
190
+ if (el) return el;
191
+ }
192
+ return document.body;
193
+ }
148
194
  function installRouteWatcher() {
149
195
  if (_routeWatcherInstalled || typeof window === "undefined") return;
150
196
  _routeWatcherInstalled = true;
151
- const dispatch = () => _routeChangeCallbacks.forEach((cb) => cb());
152
197
  const orig = {
153
198
  push: history.pushState.bind(history),
154
199
  replace: history.replaceState.bind(history)
155
200
  };
201
+ const dispatch = () => {
202
+ _routeChangeCallbacks.forEach((cb) => cb());
203
+ };
156
204
  history.pushState = (...args) => {
157
205
  orig.push(...args);
158
206
  dispatch();
@@ -164,15 +212,7 @@ function installRouteWatcher() {
164
212
  window.addEventListener("popstate", dispatch);
165
213
  window.addEventListener("hashchange", dispatch);
166
214
  }
167
- var _initialized = false;
168
- function normalizePath(p) {
169
- return p.replace(/\/$/, "").split("?")[0];
170
- }
171
- function pathMatches(current, careersPath) {
172
- const c = normalizePath(current);
173
- const target = normalizePath(careersPath);
174
- return c === target || c.startsWith(target + "/");
175
- }
215
+ var _routeChangeCallbacks = [];
176
216
  var _Prodigio = class _Prodigio {
177
217
  constructor(config) {
178
218
  // ── Jobs ──────────────────────────────────────────────────────────────────
@@ -256,11 +296,6 @@ var _Prodigio = class _Prodigio {
256
296
  static meta() {
257
297
  return { name: "prodigio-badge", content: "true" };
258
298
  }
259
- // ── destroy() ─────────────────────────────────────────────────────────────
260
- static destroy() {
261
- removeBadge();
262
- _initialized = false;
263
- }
264
299
  // ── init() ────────────────────────────────────────────────────────────────
265
300
  static async init(config) {
266
301
  var _a;
@@ -286,57 +321,86 @@ var _Prodigio = class _Prodigio {
286
321
  const hostname = window.location.hostname;
287
322
  const domainAllowed = bestToken ? bestToken.allowedDomains.length === 0 || bestToken.allowedDomains.includes(hostname) : true;
288
323
  const isExempt = bestToken !== null && !bestToken.badgeRequired && domainAllowed;
289
- let careersPath = null;
290
- function evaluateBadge() {
324
+ let configState = { status: "loading" };
325
+ function reconcile() {
326
+ cancelPending();
291
327
  if (isExempt) {
292
328
  removeBadge();
293
329
  return;
294
330
  }
295
- if (careersPath) {
296
- if (pathMatches(window.location.pathname, careersPath)) {
297
- injectBadge(position, badgeContainer);
298
- } else {
299
- removeBadge();
300
- }
301
- } else {
302
- if (!bestToken && cached) {
331
+ if (configState.status === "loading" || configState.status === "error") {
332
+ return;
333
+ }
334
+ const { careersPath } = configState;
335
+ if (!careersPath) {
336
+ if (bestToken && cached) {
303
337
  const cacheAge = Date.now() - cached.cachedAt;
304
338
  if (cacheAge < GRACE_PERIOD_MS) {
305
339
  removeBadge();
306
340
  return;
307
341
  }
308
342
  }
309
- injectBadge(position);
343
+ if (!document.getElementById(BADGE_ELEMENT_ID)) {
344
+ injectBadge(position, badgeContainer);
345
+ }
346
+ return;
347
+ }
348
+ const routeMatches = pathMatches(window.location.pathname, careersPath);
349
+ if (!routeMatches) {
350
+ removeBadge();
351
+ return;
310
352
  }
353
+ queueMicrotask(() => {
354
+ _rafHandle = requestAnimationFrame(() => {
355
+ _rafHandle = null;
356
+ const anchor = findBadgeAnchor(badgeContainer);
357
+ if (anchor) {
358
+ if (!document.getElementById(BADGE_ELEMENT_ID)) injectBadge(position, badgeContainer);
359
+ return;
360
+ }
361
+ waitForAnchor(badgeContainer, () => {
362
+ if (!document.getElementById(BADGE_ELEMENT_ID)) injectBadge(position, badgeContainer);
363
+ });
364
+ });
365
+ });
311
366
  }
312
- evaluateBadge();
367
+ reconcile();
313
368
  installRouteWatcher();
314
- _routeChangeCallbacks.push(evaluateBadge);
369
+ _routeChangeCallbacks.push(reconcile);
315
370
  setTimeout(async () => {
316
- var _a2, _b;
371
+ var _a2, _b, _c;
317
372
  try {
318
373
  const res = await fetch(`${baseUrl}/api/sdk/config?key=${encodeURIComponent(key)}`);
319
374
  if (!res.ok) return;
320
375
  const data = await res.json();
321
- if (data.careersPath !== void 0) {
322
- careersPath = data.careersPath;
323
- }
376
+ configState = {
377
+ status: "loaded",
378
+ careersPath: (_a2 = data.careersPath) != null ? _a2 : null,
379
+ badgeRequired: data.badgeRequired
380
+ };
324
381
  if (data.badgeRequired) {
325
- evaluateBadge();
382
+ reconcile();
326
383
  return;
327
384
  }
328
385
  if (data.badgeToken) {
329
386
  const refreshedClaims = await verifyBadgeToken(data.badgeToken);
330
387
  if (refreshedClaims && !refreshedClaims.badgeRequired) {
331
- cacheToken(key, data.badgeToken, (_a2 = data.badgeExemptUntil) != null ? _a2 : "", (_b = data.configVersion) != null ? _b : 1);
388
+ cacheToken(key, data.badgeToken, (_b = data.badgeExemptUntil) != null ? _b : "", (_c = data.configVersion) != null ? _c : 1);
332
389
  removeBadge();
390
+ return;
333
391
  }
334
392
  }
335
- evaluateBadge();
393
+ reconcile();
336
394
  } catch {
395
+ configState = { status: "error" };
337
396
  }
338
397
  }, 0);
339
398
  }
399
+ static destroy() {
400
+ cancelPending();
401
+ removeBadge();
402
+ _initialized = false;
403
+ }
340
404
  };
341
405
  // ── Badge static helpers ──────────────────────────────────────────────────
342
406
  _Prodigio.POWERED_BY = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prodigio-io/sdk",
3
- "version": "2.1.5",
3
+ "version": "2.1.8",
4
4
  "description": "Official JavaScript SDK for the Prodigio hiring API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",