@prodigio-io/sdk 2.1.5 → 2.1.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/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;
@@ -313,42 +348,56 @@ var _Prodigio = class _Prodigio {
313
348
  const domainAllowed = bestToken ? bestToken.allowedDomains.length === 0 || bestToken.allowedDomains.includes(hostname) : true;
314
349
  const isExempt = bestToken !== null && !bestToken.badgeRequired && domainAllowed;
315
350
  let careersPath = null;
316
- function evaluateBadge() {
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 (!careersPath) {
358
+ if (bestToken && cached) {
329
359
  const cacheAge = Date.now() - cached.cachedAt;
330
360
  if (cacheAge < GRACE_PERIOD_MS) {
331
361
  removeBadge();
332
362
  return;
333
363
  }
334
364
  }
335
- injectBadge(position);
365
+ if (!document.getElementById(BADGE_ELEMENT_ID)) {
366
+ injectBadge(position, badgeContainer);
367
+ }
368
+ return;
336
369
  }
370
+ const routeMatches = pathMatches(window.location.pathname, careersPath);
371
+ if (!routeMatches) {
372
+ removeBadge();
373
+ return;
374
+ }
375
+ queueMicrotask(() => {
376
+ _rafHandle = requestAnimationFrame(() => {
377
+ _rafHandle = null;
378
+ const anchor = findBadgeAnchor(badgeContainer);
379
+ if (anchor) {
380
+ if (!document.getElementById(BADGE_ELEMENT_ID)) injectBadge(position, badgeContainer);
381
+ return;
382
+ }
383
+ waitForAnchor(badgeContainer, () => {
384
+ if (!document.getElementById(BADGE_ELEMENT_ID)) injectBadge(position, badgeContainer);
385
+ });
386
+ });
387
+ });
337
388
  }
338
- evaluateBadge();
389
+ reconcile();
339
390
  installRouteWatcher();
340
- _routeChangeCallbacks.push(evaluateBadge);
391
+ _routeChangeCallbacks.push(reconcile);
341
392
  setTimeout(async () => {
342
393
  var _a2, _b;
343
394
  try {
344
395
  const res = await fetch(`${baseUrl}/api/sdk/config?key=${encodeURIComponent(key)}`);
345
396
  if (!res.ok) return;
346
397
  const data = await res.json();
347
- if (data.careersPath !== void 0) {
348
- careersPath = data.careersPath;
349
- }
398
+ if (data.careersPath !== void 0) careersPath = data.careersPath;
350
399
  if (data.badgeRequired) {
351
- evaluateBadge();
400
+ reconcile();
352
401
  return;
353
402
  }
354
403
  if (data.badgeToken) {
@@ -356,13 +405,19 @@ var _Prodigio = class _Prodigio {
356
405
  if (refreshedClaims && !refreshedClaims.badgeRequired) {
357
406
  cacheToken(key, data.badgeToken, (_a2 = data.badgeExemptUntil) != null ? _a2 : "", (_b = data.configVersion) != null ? _b : 1);
358
407
  removeBadge();
408
+ return;
359
409
  }
360
410
  }
361
- evaluateBadge();
411
+ reconcile();
362
412
  } catch {
363
413
  }
364
414
  }, 0);
365
415
  }
416
+ static destroy() {
417
+ cancelPending();
418
+ removeBadge();
419
+ _initialized = false;
420
+ }
366
421
  };
367
422
  // ── Badge static helpers ──────────────────────────────────────────────────
368
423
  _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;
@@ -287,42 +322,56 @@ var _Prodigio = class _Prodigio {
287
322
  const domainAllowed = bestToken ? bestToken.allowedDomains.length === 0 || bestToken.allowedDomains.includes(hostname) : true;
288
323
  const isExempt = bestToken !== null && !bestToken.badgeRequired && domainAllowed;
289
324
  let careersPath = null;
290
- function evaluateBadge() {
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 (!careersPath) {
332
+ if (bestToken && cached) {
303
333
  const cacheAge = Date.now() - cached.cachedAt;
304
334
  if (cacheAge < GRACE_PERIOD_MS) {
305
335
  removeBadge();
306
336
  return;
307
337
  }
308
338
  }
309
- injectBadge(position);
339
+ if (!document.getElementById(BADGE_ELEMENT_ID)) {
340
+ injectBadge(position, badgeContainer);
341
+ }
342
+ return;
310
343
  }
344
+ const routeMatches = pathMatches(window.location.pathname, careersPath);
345
+ if (!routeMatches) {
346
+ removeBadge();
347
+ return;
348
+ }
349
+ queueMicrotask(() => {
350
+ _rafHandle = requestAnimationFrame(() => {
351
+ _rafHandle = null;
352
+ const anchor = findBadgeAnchor(badgeContainer);
353
+ if (anchor) {
354
+ if (!document.getElementById(BADGE_ELEMENT_ID)) injectBadge(position, badgeContainer);
355
+ return;
356
+ }
357
+ waitForAnchor(badgeContainer, () => {
358
+ if (!document.getElementById(BADGE_ELEMENT_ID)) injectBadge(position, badgeContainer);
359
+ });
360
+ });
361
+ });
311
362
  }
312
- evaluateBadge();
363
+ reconcile();
313
364
  installRouteWatcher();
314
- _routeChangeCallbacks.push(evaluateBadge);
365
+ _routeChangeCallbacks.push(reconcile);
315
366
  setTimeout(async () => {
316
367
  var _a2, _b;
317
368
  try {
318
369
  const res = await fetch(`${baseUrl}/api/sdk/config?key=${encodeURIComponent(key)}`);
319
370
  if (!res.ok) return;
320
371
  const data = await res.json();
321
- if (data.careersPath !== void 0) {
322
- careersPath = data.careersPath;
323
- }
372
+ if (data.careersPath !== void 0) careersPath = data.careersPath;
324
373
  if (data.badgeRequired) {
325
- evaluateBadge();
374
+ reconcile();
326
375
  return;
327
376
  }
328
377
  if (data.badgeToken) {
@@ -330,13 +379,19 @@ var _Prodigio = class _Prodigio {
330
379
  if (refreshedClaims && !refreshedClaims.badgeRequired) {
331
380
  cacheToken(key, data.badgeToken, (_a2 = data.badgeExemptUntil) != null ? _a2 : "", (_b = data.configVersion) != null ? _b : 1);
332
381
  removeBadge();
382
+ return;
333
383
  }
334
384
  }
335
- evaluateBadge();
385
+ reconcile();
336
386
  } catch {
337
387
  }
338
388
  }, 0);
339
389
  }
390
+ static destroy() {
391
+ cancelPending();
392
+ removeBadge();
393
+ _initialized = false;
394
+ }
340
395
  };
341
396
  // ── Badge static helpers ──────────────────────────────────────────────────
342
397
  _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.7",
4
4
  "description": "Official JavaScript SDK for the Prodigio hiring API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",