fauxbase 0.5.4 → 0.5.6

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.cts CHANGED
@@ -50,6 +50,11 @@ interface LocalDriverConfig {
50
50
  type: 'local';
51
51
  persist?: 'memory' | 'localStorage' | 'indexeddb';
52
52
  dbName?: string;
53
+ latency?: number | {
54
+ min: number;
55
+ max: number;
56
+ };
57
+ errorRate?: number;
53
58
  }
54
59
  interface HttpDriverConfig {
55
60
  type: 'http';
@@ -141,6 +146,7 @@ interface Driver {
141
146
  method?: string;
142
147
  body?: any;
143
148
  query?: Record<string, string>;
149
+ local?: () => R | Promise<R>;
144
150
  }): Promise<R>;
145
151
  seed(resource: string, data: Array<Record<string, any>>, entityClass: Function): void;
146
152
  getSeedVersion(): string | null;
@@ -232,6 +238,7 @@ declare abstract class Service<T extends Entity> {
232
238
  method?: string;
233
239
  body?: any;
234
240
  query?: Record<string, string>;
241
+ local?: () => R | Promise<R>;
235
242
  }): Promise<R>;
236
243
  private emitEvent;
237
244
  private runHooks;
@@ -283,6 +290,7 @@ declare class HttpDriver implements Driver {
283
290
  method?: string;
284
291
  body?: any;
285
292
  query?: Record<string, string>;
293
+ local?: () => R | Promise<R>;
286
294
  }): Promise<R>;
287
295
  seed(): void;
288
296
  getSeedVersion(): string | null;
@@ -375,7 +383,11 @@ declare class LocalDriver implements Driver {
375
383
  private authProvider;
376
384
  private _ready;
377
385
  private _isReady;
386
+ private latencyMs;
387
+ private errorRate;
378
388
  constructor(config: LocalDriverConfig);
389
+ private simulate;
390
+ private getLatency;
379
391
  get ready(): Promise<void>;
380
392
  get isReady(): boolean;
381
393
  setAuthProvider(provider: AuthProvider): void;
@@ -395,10 +407,11 @@ declare class LocalDriver implements Driver {
395
407
  bulkDelete(resource: string, ids: string[]): Promise<ApiResponse<{
396
408
  count: number;
397
409
  }>>;
398
- request<R = any>(_resource: string, _path: string, _options?: {
410
+ request<R = any>(_resource: string, _path: string, options?: {
399
411
  method?: string;
400
412
  body?: any;
401
413
  query?: Record<string, string>;
414
+ local?: () => R | Promise<R>;
402
415
  }): Promise<R>;
403
416
  seed(resource: string, data: Array<Record<string, any>>, entityClass: Function): void;
404
417
  getSeedVersion(): string | null;
package/dist/index.d.ts CHANGED
@@ -50,6 +50,11 @@ interface LocalDriverConfig {
50
50
  type: 'local';
51
51
  persist?: 'memory' | 'localStorage' | 'indexeddb';
52
52
  dbName?: string;
53
+ latency?: number | {
54
+ min: number;
55
+ max: number;
56
+ };
57
+ errorRate?: number;
53
58
  }
54
59
  interface HttpDriverConfig {
55
60
  type: 'http';
@@ -141,6 +146,7 @@ interface Driver {
141
146
  method?: string;
142
147
  body?: any;
143
148
  query?: Record<string, string>;
149
+ local?: () => R | Promise<R>;
144
150
  }): Promise<R>;
145
151
  seed(resource: string, data: Array<Record<string, any>>, entityClass: Function): void;
146
152
  getSeedVersion(): string | null;
@@ -232,6 +238,7 @@ declare abstract class Service<T extends Entity> {
232
238
  method?: string;
233
239
  body?: any;
234
240
  query?: Record<string, string>;
241
+ local?: () => R | Promise<R>;
235
242
  }): Promise<R>;
236
243
  private emitEvent;
237
244
  private runHooks;
@@ -283,6 +290,7 @@ declare class HttpDriver implements Driver {
283
290
  method?: string;
284
291
  body?: any;
285
292
  query?: Record<string, string>;
293
+ local?: () => R | Promise<R>;
286
294
  }): Promise<R>;
287
295
  seed(): void;
288
296
  getSeedVersion(): string | null;
@@ -375,7 +383,11 @@ declare class LocalDriver implements Driver {
375
383
  private authProvider;
376
384
  private _ready;
377
385
  private _isReady;
386
+ private latencyMs;
387
+ private errorRate;
378
388
  constructor(config: LocalDriverConfig);
389
+ private simulate;
390
+ private getLatency;
379
391
  get ready(): Promise<void>;
380
392
  get isReady(): boolean;
381
393
  setAuthProvider(provider: AuthProvider): void;
@@ -395,10 +407,11 @@ declare class LocalDriver implements Driver {
395
407
  bulkDelete(resource: string, ids: string[]): Promise<ApiResponse<{
396
408
  count: number;
397
409
  }>>;
398
- request<R = any>(_resource: string, _path: string, _options?: {
410
+ request<R = any>(_resource: string, _path: string, options?: {
399
411
  method?: string;
400
412
  body?: any;
401
413
  query?: Record<string, string>;
414
+ local?: () => R | Promise<R>;
402
415
  }): Promise<R>;
403
416
  seed(resource: string, data: Array<Record<string, any>>, entityClass: Function): void;
404
417
  getSeedVersion(): string | null;
package/dist/index.js CHANGED
@@ -242,6 +242,13 @@ var Service = class {
242
242
  };
243
243
  }
244
244
  async request(path, options) {
245
+ if (options?.local) {
246
+ try {
247
+ return this.driver.request(this.resourceName, path, options);
248
+ } catch {
249
+ return options.local();
250
+ }
251
+ }
245
252
  return this.driver.request(this.resourceName, path, options);
246
253
  }
247
254
  emitEvent(action, extra) {
@@ -739,7 +746,11 @@ var LocalDriver = class {
739
746
  authProvider = null;
740
747
  _ready;
741
748
  _isReady;
749
+ latencyMs;
750
+ errorRate;
742
751
  constructor(config) {
752
+ this.latencyMs = config.latency ?? 0;
753
+ this.errorRate = config.errorRate ?? 0;
743
754
  if (config.persist === "indexeddb") {
744
755
  const backend = new IndexedDBBackend(config.dbName ?? "fauxbase");
745
756
  this.storage = backend;
@@ -753,6 +764,27 @@ var LocalDriver = class {
753
764
  this._ready = Promise.resolve();
754
765
  }
755
766
  }
767
+ async simulate() {
768
+ if (this.errorRate > 0 && Math.random() < this.errorRate) {
769
+ const errors = [
770
+ () => new NetworkError("Simulated network failure"),
771
+ () => new TimeoutError("Simulated request timeout"),
772
+ () => new NetworkError("Simulated connection refused")
773
+ ];
774
+ const delay2 = this.getLatency();
775
+ if (delay2 > 0) await new Promise((r) => setTimeout(r, delay2 / 2));
776
+ throw errors[Math.floor(Math.random() * errors.length)]();
777
+ }
778
+ const delay = this.getLatency();
779
+ if (delay > 0) {
780
+ await new Promise((r) => setTimeout(r, delay));
781
+ }
782
+ }
783
+ getLatency() {
784
+ if (typeof this.latencyMs === "number") return this.latencyMs;
785
+ const { min, max } = this.latencyMs;
786
+ return Math.floor(Math.random() * (max - min + 1)) + min;
787
+ }
756
788
  get ready() {
757
789
  return this._ready;
758
790
  }
@@ -769,12 +801,14 @@ var LocalDriver = class {
769
801
  this.entityClasses.set(resource, entityClass);
770
802
  }
771
803
  async list(resource, query) {
804
+ await this.simulate();
772
805
  const items = this.storage.getAll(resource);
773
806
  const entityClass = this.entityClasses.get(resource);
774
807
  const processed = entityClass ? items.map((item) => applyComputedFields(item, entityClass)) : items;
775
808
  return executeQuery(processed, query);
776
809
  }
777
810
  async get(resource, id) {
811
+ await this.simulate();
778
812
  const item = this.storage.getById(resource, id);
779
813
  if (!item || item.deletedAt) {
780
814
  throw new NotFoundError(`${resource} with id "${id}" not found`);
@@ -784,6 +818,7 @@ var LocalDriver = class {
784
818
  return { data };
785
819
  }
786
820
  async create(resource, data) {
821
+ await this.simulate();
787
822
  const entityClass = this.entityClasses.get(resource);
788
823
  const now = (/* @__PURE__ */ new Date()).toISOString();
789
824
  const authContext = this.authProvider?.();
@@ -810,6 +845,7 @@ var LocalDriver = class {
810
845
  return { data: result };
811
846
  }
812
847
  async update(resource, id, data) {
848
+ await this.simulate();
813
849
  const existing = this.storage.getById(resource, id);
814
850
  if (!existing || existing.deletedAt) {
815
851
  throw new NotFoundError(`${resource} with id "${id}" not found`);
@@ -836,6 +872,7 @@ var LocalDriver = class {
836
872
  return { data: result };
837
873
  }
838
874
  async delete(resource, id) {
875
+ await this.simulate();
839
876
  const existing = this.storage.getById(resource, id);
840
877
  if (!existing || existing.deletedAt) {
841
878
  throw new NotFoundError(`${resource} with id "${id}" not found`);
@@ -858,6 +895,7 @@ var LocalDriver = class {
858
895
  return { data: record };
859
896
  }
860
897
  async count(resource, filter) {
898
+ await this.simulate();
861
899
  let items = this.storage.getAll(resource).filter((item) => !item.deletedAt);
862
900
  if (filter) {
863
901
  items = applyFilters(items, filter);
@@ -888,9 +926,12 @@ var LocalDriver = class {
888
926
  }
889
927
  return { data: { count } };
890
928
  }
891
- async request(_resource, _path, _options) {
929
+ async request(_resource, _path, options) {
930
+ if (options?.local) {
931
+ return options.local();
932
+ }
892
933
  throw new Error(
893
- "service.request() is only available with the HTTP driver. Local driver does not support custom endpoints."
934
+ "service.request() is only available with the HTTP driver. Provide a `local` handler or switch to HTTP driver."
894
935
  );
895
936
  }
896
937
  // --- Seed management (synchronous) ---