@altazion/commerce-sdk-core 26.409.7573 → 26.415.7673

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.ts CHANGED
@@ -178,9 +178,8 @@ export declare interface CartLineDiscount {
178
178
  declare class CartModule {
179
179
  private readonly http;
180
180
  private readonly cache;
181
- private readonly queue;
182
181
  private readonly connectivity;
183
- constructor(http: CommerceHttpAdapter, cache: CacheStrategy, queue: OfflineQueue, connectivity: ConnectivityManager);
182
+ constructor(http: CommerceHttpAdapter, cache: CacheStrategy, connectivity: ConnectivityManager);
184
183
  /** Récupère le panier en cours */
185
184
  getCart(): Promise<Cart>;
186
185
  /** Récupère le statut de validation du panier */
@@ -195,6 +194,7 @@ declare class CartModule {
195
194
  applyCoupon(code: string): Promise<Cart>;
196
195
  /** Retire un coupon */
197
196
  removeCoupon(code: string): Promise<Cart>;
197
+ private ensureOnline;
198
198
  }
199
199
 
200
200
  export declare interface CartPayment {
@@ -254,29 +254,17 @@ export declare class CommerceClient {
254
254
  private readonly http;
255
255
  private readonly workerBridge;
256
256
  private readonly cacheStrategy;
257
- private readonly offlineQueue;
258
257
  private readonly sessionManager;
259
- private unsubscribeOnline;
260
258
  constructor(options: CommerceContextOptions);
261
259
  /**
262
260
  * Initialise le SDK :
263
261
  * - Crée la session si nécessaire (mode browser uniquement)
264
- * - Abonne le flush automatique de la file hors-ligne au retour en ligne
265
262
  */
266
263
  initialize(): Promise<SessionInfo | null>;
267
264
  /**
268
265
  * Retourne vrai si le SDK est hors-ligne.
269
266
  */
270
267
  get isOffline(): boolean;
271
- /**
272
- * Retourne le nombre d'opérations en attente dans la file hors-ligne.
273
- */
274
- get pendingOperationsCount(): Promise<number>;
275
- /**
276
- * Abonne un listener aux événements de la file hors-ligne.
277
- * Retourne une fonction de désabonnement.
278
- */
279
- onQueueEvent(listener: Parameters<OfflineQueue['subscribe']>[0]): () => void;
280
268
  /**
281
269
  * Force le vidage du cache.
282
270
  */
@@ -464,35 +452,6 @@ export declare class OfflineError extends Error {
464
452
  constructor(message?: string);
465
453
  }
466
454
 
467
- /**
468
- * File d'attente persistante (IndexedDB) pour les mutations effectuées hors-ligne.
469
- *
470
- * Flux :
471
- * 1. `enqueue(operation)` — stocke l'opération en IndexedDB
472
- * 2. Au retour en ligne, `flush()` rejoue les opérations dans l'ordre d'enfilage
473
- * 3. En cas d'erreur 4xx (conflit) : émet un événement `conflict` et ne retire PAS l'opération
474
- * 4. En cas de succès : retire l'opération de la file
475
- */
476
- declare class OfflineQueue {
477
- private db;
478
- private readonly listeners;
479
- private counter;
480
- /** Abonne un listener aux événements de file. Retourne une fonction de désabonnement. */
481
- subscribe(listener: QueueEventListener): () => void;
482
- get pendingCount(): Promise<number>;
483
- enqueue(method: QueuedOperation['method'], path: string, body?: unknown, headers?: Record<string, string>): Promise<QueuedOperation>;
484
- /**
485
- * Rejoue toutes les opérations en attente dans l'ordre d'enfilage.
486
- * S'arrête sur un conflit (4xx) et émet un événement `conflict`.
487
- */
488
- flush(http: CommerceHttpAdapter): Promise<void>;
489
- private emit;
490
- private openDb;
491
- private put;
492
- private remove;
493
- private getAll;
494
- }
495
-
496
455
  /** Point de livraison (point relais, locker, consigne) */
497
456
  export declare interface PickupPoint {
498
457
  id: string;
@@ -643,45 +602,6 @@ export declare interface ProductWebAvailability {
643
602
  source: AvailabilitySource;
644
603
  }
645
604
 
646
- /**
647
- * Représente une opération en attente dans la file hors-ligne.
648
- */
649
- export declare interface QueuedOperation {
650
- /** Identifiant unique de l'opération */
651
- id: string;
652
- /** Timestamp d'enfilage */
653
- enqueuedAt: number;
654
- /** Méthode HTTP */
655
- method: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
656
- /** Path de la requête (sans baseUrl) */
657
- path: string;
658
- /** Corps de la requête sérialisé */
659
- body: unknown;
660
- /** Headers supplémentaires */
661
- headers?: Record<string, string>;
662
- /** Nombre de tentatives déjà effectuées */
663
- attempts: number;
664
- }
665
-
666
- export declare interface QueueEvent {
667
- type: QueueEventType;
668
- operation?: QueuedOperation;
669
- error?: QueueFlushError;
670
- }
671
-
672
- export declare type QueueEventListener = (event: QueueEvent) => void;
673
-
674
- export declare type QueueEventType = 'enqueued' | 'flushed' | 'conflict' | 'emptied';
675
-
676
- /**
677
- * Erreur levée lors du rejeu de l'OfflineQueue (conflit serveur).
678
- */
679
- export declare class QueueFlushError extends Error {
680
- readonly failedOperationId: string;
681
- readonly apiError: AltazionApiError;
682
- constructor(operationId: string, apiError: AltazionApiError);
683
- }
684
-
685
605
  declare interface RequestOptions {
686
606
  method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
687
607
  body?: unknown;
@@ -52,16 +52,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
52
52
  this.cause = cause;
53
53
  }
54
54
  }
55
- class QueueFlushError extends Error {
56
- constructor(operationId, apiError) {
57
- super(`Échec du rejeu de l'opération ${operationId} : ${apiError.message}`);
58
- __publicField(this, "failedOperationId");
59
- __publicField(this, "apiError");
60
- this.name = "QueueFlushError";
61
- this.failedOperationId = operationId;
62
- this.apiError = apiError;
63
- }
64
- }
65
55
  class CommerceHttpAdapter {
66
56
  constructor(context) {
67
57
  __publicField(this, "context");
@@ -353,139 +343,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
353
343
  return data;
354
344
  }
355
345
  }
356
- const DB_NAME = "altazion-queue";
357
- const DB_VERSION = 1;
358
- const STORE_NAME = "operations";
359
- class OfflineQueue {
360
- constructor() {
361
- __publicField(this, "db", null);
362
- __publicField(this, "listeners", /* @__PURE__ */ new Set());
363
- __publicField(this, "counter", 0);
364
- }
365
- /** Abonne un listener aux événements de file. Retourne une fonction de désabonnement. */
366
- subscribe(listener) {
367
- this.listeners.add(listener);
368
- return () => this.listeners.delete(listener);
369
- }
370
- get pendingCount() {
371
- return this.openDb().then(
372
- (db) => new Promise((resolve, reject) => {
373
- const tx = db.transaction(STORE_NAME, "readonly");
374
- const req = tx.objectStore(STORE_NAME).count();
375
- req.onsuccess = () => resolve(req.result);
376
- req.onerror = () => reject(req.error);
377
- })
378
- );
379
- }
380
- async enqueue(method, path, body, headers) {
381
- const operation = {
382
- id: `${Date.now()}-${++this.counter}`,
383
- enqueuedAt: Date.now(),
384
- method,
385
- path,
386
- body,
387
- headers,
388
- attempts: 0
389
- };
390
- const db = await this.openDb();
391
- await this.put(db, operation);
392
- this.emit({ type: "enqueued", operation });
393
- return operation;
394
- }
395
- /**
396
- * Rejoue toutes les opérations en attente dans l'ordre d'enfilage.
397
- * S'arrête sur un conflit (4xx) et émet un événement `conflict`.
398
- */
399
- async flush(http) {
400
- const operations = await this.getAll();
401
- if (operations.length === 0) return;
402
- for (const op of operations) {
403
- try {
404
- op.attempts++;
405
- await http.request(op.path, {
406
- method: op.method,
407
- body: op.body,
408
- headers: op.headers
409
- });
410
- await this.remove(op.id);
411
- } catch (err) {
412
- if (err instanceof AltazionApiError && err.status >= 400 && err.status < 500) {
413
- const flushError = new QueueFlushError(op.id, err);
414
- this.emit({ type: "conflict", operation: op, error: flushError });
415
- return;
416
- }
417
- await this.put(await this.openDb(), op);
418
- return;
419
- }
420
- }
421
- this.emit({ type: "flushed" });
422
- const remaining = await this.pendingCount;
423
- if (remaining === 0) {
424
- this.emit({ type: "emptied" });
425
- }
426
- }
427
- emit(event) {
428
- for (const listener of this.listeners) {
429
- try {
430
- listener(event);
431
- } catch {
432
- }
433
- }
434
- }
435
- openDb() {
436
- return new Promise((resolve, reject) => {
437
- if (this.db) {
438
- resolve(this.db);
439
- return;
440
- }
441
- const request = indexedDB.open(DB_NAME, DB_VERSION);
442
- request.onupgradeneeded = (event) => {
443
- const database = event.target.result;
444
- if (!database.objectStoreNames.contains(STORE_NAME)) {
445
- database.createObjectStore(STORE_NAME, { keyPath: "id" });
446
- }
447
- };
448
- request.onsuccess = (event) => {
449
- this.db = event.target.result;
450
- resolve(this.db);
451
- };
452
- request.onerror = () => reject(request.error);
453
- });
454
- }
455
- put(db, operation) {
456
- return new Promise((resolve, reject) => {
457
- const tx = db.transaction(STORE_NAME, "readwrite");
458
- const req = tx.objectStore(STORE_NAME).put(operation);
459
- req.onsuccess = () => resolve();
460
- req.onerror = () => reject(req.error);
461
- });
462
- }
463
- remove(id) {
464
- return this.openDb().then(
465
- (db) => new Promise((resolve, reject) => {
466
- const tx = db.transaction(STORE_NAME, "readwrite");
467
- const req = tx.objectStore(STORE_NAME).delete(id);
468
- req.onsuccess = () => resolve();
469
- req.onerror = () => reject(req.error);
470
- })
471
- );
472
- }
473
- getAll() {
474
- return this.openDb().then(
475
- (db) => new Promise((resolve, reject) => {
476
- const tx = db.transaction(STORE_NAME, "readonly");
477
- const req = tx.objectStore(STORE_NAME).getAll();
478
- req.onsuccess = () => {
479
- const ops = req.result.sort(
480
- (a, b) => a.enqueuedAt - b.enqueuedAt
481
- );
482
- resolve(ops);
483
- };
484
- req.onerror = () => reject(req.error);
485
- })
486
- );
487
- }
488
- }
489
346
  class BrowserSessionManager {
490
347
  constructor(http, context) {
491
348
  __publicField(this, "http");
@@ -560,10 +417,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
560
417
  }
561
418
  }
562
419
  class CartModule {
563
- constructor(http, cache, queue, connectivity) {
420
+ constructor(http, cache, connectivity) {
564
421
  this.http = http;
565
422
  this.cache = cache;
566
- this.queue = queue;
567
423
  this.connectivity = connectivity;
568
424
  }
569
425
  /** Récupère le panier en cours */
@@ -580,48 +436,46 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
580
436
  }
581
437
  /** Ajoute un article au panier */
582
438
  async addItem(reference, quantity, options) {
439
+ this.ensureOnline();
583
440
  const body = { reference, quantity, ...options };
584
- if (this.connectivity.isOffline) {
585
- await this.queue.enqueue("POST", "/commerce/api/process/cart/items", body);
586
- return this.cache.execute("cart:current", () => this.http.get("/commerce/api/process/cart"), "network-first");
587
- }
588
441
  const cart = await this.http.post("/commerce/api/process/cart/items", body);
589
442
  await this.cache.execute("cart:current", () => Promise.resolve(cart), "network-first");
590
443
  return cart;
591
444
  }
592
445
  /** Met à jour la quantité d'une ligne */
593
446
  async updateItem(lineId, quantity) {
447
+ this.ensureOnline();
594
448
  const body = { quantity };
595
- if (this.connectivity.isOffline) {
596
- await this.queue.enqueue("PUT", `/commerce/api/process/cart/items/${lineId}`, body);
597
- return this.cache.execute("cart:current", () => this.http.get("/commerce/api/process/cart"), "network-first");
598
- }
599
449
  const cart = await this.http.put(`/commerce/api/process/cart/items/${lineId}`, body);
600
450
  await this.cache.execute("cart:current", () => Promise.resolve(cart), "network-first");
601
451
  return cart;
602
452
  }
603
453
  /** Supprime une ligne du panier */
604
454
  async removeItem(lineId) {
605
- if (this.connectivity.isOffline) {
606
- await this.queue.enqueue("DELETE", `/commerce/api/process/cart/items/${lineId}`);
607
- return this.cache.execute("cart:current", () => this.http.get("/commerce/api/process/cart"), "network-first");
608
- }
455
+ this.ensureOnline();
609
456
  const cart = await this.http.delete(`/commerce/api/process/cart/items/${lineId}`);
610
457
  await this.cache.execute("cart:current", () => Promise.resolve(cart), "network-first");
611
458
  return cart;
612
459
  }
613
460
  /** Applique un coupon */
614
461
  async applyCoupon(code) {
462
+ this.ensureOnline();
615
463
  const cart = await this.http.post("/commerce/api/process/cart/coupons", { code });
616
464
  await this.cache.execute("cart:current", () => Promise.resolve(cart), "network-first");
617
465
  return cart;
618
466
  }
619
467
  /** Retire un coupon */
620
468
  async removeCoupon(code) {
469
+ this.ensureOnline();
621
470
  const cart = await this.http.delete(`/commerce/api/process/cart/coupons/${encodeURIComponent(code)}`);
622
471
  await this.cache.execute("cart:current", () => Promise.resolve(cart), "network-first");
623
472
  return cart;
624
473
  }
474
+ ensureOnline() {
475
+ if (this.connectivity.isOffline) {
476
+ throw new OfflineError("Le terminal est hors ligne, les modifications du panier sont indisponibles");
477
+ }
478
+ }
625
479
  }
626
480
  class CatalogModule {
627
481
  constructor(http, cache) {
@@ -786,18 +640,15 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
786
640
  __publicField(this, "http");
787
641
  __publicField(this, "workerBridge");
788
642
  __publicField(this, "cacheStrategy");
789
- __publicField(this, "offlineQueue");
790
643
  __publicField(this, "sessionManager");
791
- __publicField(this, "unsubscribeOnline", null);
792
644
  this.context = new CommerceContext(options);
793
645
  this.http = new CommerceHttpAdapter(this.context);
794
646
  this.connectivity = new ConnectivityManager();
795
647
  this.workerBridge = new WorkerBridge();
796
648
  this.cacheStrategy = new CacheStrategy(this.workerBridge, this.http);
797
- this.offlineQueue = new OfflineQueue();
798
649
  this.sessionManager = SessionManagerFactory.create(this.http, this.context);
799
650
  this.session = new SessionModule(this.http, this.cacheStrategy);
800
- this.cart = new CartModule(this.http, this.cacheStrategy, this.offlineQueue, this.connectivity);
651
+ this.cart = new CartModule(this.http, this.cacheStrategy, this.connectivity);
801
652
  this.catalog = new CatalogModule(this.http, this.cacheStrategy);
802
653
  this.shipping = new ShippingModule(this.http, this.cacheStrategy);
803
654
  this.marketing = new MarketingModule(this.http, this.cacheStrategy);
@@ -806,14 +657,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
806
657
  /**
807
658
  * Initialise le SDK :
808
659
  * - Crée la session si nécessaire (mode browser uniquement)
809
- * - Abonne le flush automatique de la file hors-ligne au retour en ligne
810
660
  */
811
661
  async initialize() {
812
- this.unsubscribeOnline = this.connectivity.subscribe(async (status) => {
813
- if (status === "online") {
814
- await this.offlineQueue.flush(this.http);
815
- }
816
- });
817
662
  return this.sessionManager.initialize();
818
663
  }
819
664
  /**
@@ -822,19 +667,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
822
667
  get isOffline() {
823
668
  return this.connectivity.isOffline;
824
669
  }
825
- /**
826
- * Retourne le nombre d'opérations en attente dans la file hors-ligne.
827
- */
828
- get pendingOperationsCount() {
829
- return this.offlineQueue.pendingCount;
830
- }
831
- /**
832
- * Abonne un listener aux événements de la file hors-ligne.
833
- * Retourne une fonction de désabonnement.
834
- */
835
- onQueueEvent(listener) {
836
- return this.offlineQueue.subscribe(listener);
837
- }
838
670
  /**
839
671
  * Force le vidage du cache.
840
672
  */
@@ -845,8 +677,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
845
677
  * Libère les ressources (listeners, worker).
846
678
  */
847
679
  dispose() {
848
- var _a;
849
- (_a = this.unsubscribeOnline) == null ? void 0 : _a.call(this);
850
680
  this.connectivity.dispose();
851
681
  this.workerBridge.dispose();
852
682
  }
@@ -857,7 +687,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
857
687
  exports.CommerceContext = CommerceContext;
858
688
  exports.ConnectivityManager = ConnectivityManager;
859
689
  exports.OfflineError = OfflineError;
860
- exports.QueueFlushError = QueueFlushError;
861
690
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
862
691
  return exports;
863
692
  }({});