@luvio/adapter-test-library 0.62.4 → 0.63.3

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.
@@ -1,11 +1,11 @@
1
1
  import { DurableStore, DurableStoreEntries, OnDurableStoreChangedListener, DurableStoreOperation, DurableStoreChange } from '@luvio/environments';
2
+ import { DurableStorePersistence } from './durableStorePersistence';
2
3
  export declare class MockDurableStore implements DurableStore {
3
4
  listeners: Set<OnDurableStoreChangedListener>;
4
- segments: {
5
- [id: string]: DurableStoreEntries<unknown>;
6
- };
5
+ persistence: DurableStorePersistence;
6
+ constructor(persistence?: DurableStorePersistence);
7
7
  getEntries<T>(entryIds: string[], segment: string): Promise<DurableStoreEntries<T> | undefined>;
8
- getAllEntries<T>(segment: string): Promise<DurableStoreEntries<T> | undefined>;
8
+ getAllEntries<T>(segment: string): Promise<DurableStoreEntries<T>>;
9
9
  setEntries<T>(entries: DurableStoreEntries<T>, segment: string): Promise<void>;
10
10
  evictEntries(ids: string[], segment: string): Promise<void>;
11
11
  registerOnChangedListener(listener: OnDurableStoreChangedListener): () => Promise<void>;
@@ -0,0 +1,11 @@
1
+ export interface DurableStorePersistence {
2
+ get<T>(key: string): Promise<T | undefined>;
3
+ set<T>(key: string, value: T): Promise<void>;
4
+ delete(key: string): Promise<void>;
5
+ }
6
+ export declare class MemoryDurableStorePersistence implements DurableStorePersistence {
7
+ private store;
8
+ get<T>(key: string): Promise<T | undefined>;
9
+ set<T>(key: string, value: T): Promise<void>;
10
+ delete(key: string): Promise<void>;
11
+ }
@@ -3,3 +3,4 @@ export { verifyImmutable, isImmutable } from './verification';
3
3
  export { getMockLuvioWithFulfilledSnapshot, getMockFulfilledSnapshot } from './mocks';
4
4
  export { stripProperties } from './utils';
5
5
  export { MockDurableStore } from './durableStore';
6
+ export { MemoryDurableStorePersistence, DurableStorePersistence } from './durableStorePersistence';
@@ -277,35 +277,51 @@ function getMockFulfilledSnapshot() {
277
277
  return mockFulfilledSnapshot;
278
278
  }
279
279
 
280
- class MockDurableStore {
280
+ class MemoryDurableStorePersistence {
281
281
  constructor() {
282
+ this.store = {};
283
+ }
284
+ async get(key) {
285
+ return this.store[key];
286
+ }
287
+ async set(key, value) {
288
+ this.store[key] = value;
289
+ }
290
+ async delete(key) {
291
+ delete this.store[key];
292
+ }
293
+ }
294
+
295
+ class MockDurableStore {
296
+ constructor(persistence) {
297
+ // NOTE: This mock class doesn't enforce read/write synchronization
282
298
  this.listeners = new Set();
283
- this.segments = {};
299
+ this.persistence = persistence || new MemoryDurableStorePersistence();
284
300
  }
285
301
  getEntries(entryIds, segment) {
286
302
  const returnSource = Object.create(null);
287
- const entries = this.segments[segment];
288
- if (entries === undefined) {
289
- return Promise.resolve(undefined);
290
- }
291
- for (const entryId of entryIds) {
292
- const entry = entries[entryId];
293
- if (entry !== undefined) {
294
- returnSource[entryId] = clone(entry);
303
+ return this.persistence.get(segment).then((entries) => {
304
+ if (entries === undefined) {
305
+ return undefined;
295
306
  }
296
- }
297
- return Promise.resolve(returnSource);
307
+ for (const entryId of entryIds) {
308
+ const entry = entries[entryId];
309
+ if (entry !== undefined) {
310
+ returnSource[entryId] = clone(entry);
311
+ }
312
+ }
313
+ return returnSource;
314
+ });
298
315
  }
299
316
  getAllEntries(segment) {
300
317
  const returnSource = Object.create(null);
301
- let entries = this.segments[segment];
302
- if (entries === undefined) {
303
- entries = {};
304
- }
305
- for (const key of Object.keys(entries)) {
306
- returnSource[key] = clone(entries[key]);
307
- }
308
- return Promise.resolve(returnSource);
318
+ return this.persistence.get(segment).then((rawEntries) => {
319
+ const entries = rawEntries === undefined ? {} : rawEntries;
320
+ for (const key of Object.keys(entries)) {
321
+ returnSource[key] = clone(entries[key]);
322
+ }
323
+ return returnSource;
324
+ });
309
325
  }
310
326
  setEntries(entries, segment) {
311
327
  return this.batchOperations([
@@ -324,41 +340,36 @@ class MockDurableStore {
324
340
  return Promise.resolve();
325
341
  };
326
342
  }
327
- batchOperations(operations) {
328
- const allPromises = operations.map((operation) => {
329
- return this.performOperation(operation);
330
- });
331
- return Promise.all(allPromises).then((changes) => {
332
- // IMPORTANT - listeners are called after `.then` so it's on the next
333
- // tick
334
- this.listeners.forEach((listener) => {
335
- listener(changes);
336
- });
343
+ async batchOperations(operations) {
344
+ const changes = [];
345
+ for (let i = 0; i < operations.length; i++) {
346
+ changes.push(await this.performOperation(operations[i]));
347
+ }
348
+ this.listeners.forEach((listener) => {
349
+ listener(changes);
337
350
  });
338
351
  }
339
- performOperation(operation) {
352
+ async performOperation(operation) {
340
353
  const segment = operation.segment;
341
- let existingEntries = this.segments[segment];
342
- if (existingEntries === undefined) {
343
- existingEntries = {};
344
- }
345
- let ids;
354
+ const rawEntries = await this.persistence.get(segment);
355
+ const entries = rawEntries === undefined ? {} : rawEntries;
356
+ let ids = [];
346
357
  switch (operation.type) {
347
358
  case DurableStoreOperationType.SetEntries:
348
359
  ids = Object.keys(operation.entries);
349
360
  ids.forEach((id) => {
350
- existingEntries[id] = clone(operation.entries[id]);
361
+ entries[id] = clone(operation.entries[id]);
351
362
  });
352
363
  break;
353
364
  case DurableStoreOperationType.EvictEntries:
354
365
  ids = operation.ids;
355
366
  ids.forEach((id) => {
356
- delete existingEntries[id];
367
+ delete entries[id];
357
368
  });
358
369
  }
359
- this.segments[operation.segment] = existingEntries;
360
- return Promise.resolve({ ids, segment, type: operation.type });
370
+ await this.persistence.set(operation.segment, entries);
371
+ return { ids, segment, type: operation.type };
361
372
  }
362
373
  }
363
374
 
364
- export { ConnectivityState, MockDurableStore, buildErrorMockPayload, buildFetchResponse, buildMockNetworkAdapter, buildSuccessMockPayload, getMockFulfilledSnapshot, getMockLuvioWithFulfilledSnapshot, getMockNetworkAdapterCallCount, isImmutable, overrideMockNetworkResponses, resetMockNetworkAdapter, setMockNetworkPayloads, setNetworkConnectivity, stripProperties, verifyImmutable };
375
+ export { ConnectivityState, MemoryDurableStorePersistence, MockDurableStore, buildErrorMockPayload, buildFetchResponse, buildMockNetworkAdapter, buildSuccessMockPayload, getMockFulfilledSnapshot, getMockLuvioWithFulfilledSnapshot, getMockNetworkAdapterCallCount, isImmutable, overrideMockNetworkResponses, resetMockNetworkAdapter, setMockNetworkPayloads, setNetworkConnectivity, stripProperties, verifyImmutable };
@@ -1,11 +1,11 @@
1
1
  import { DurableStore, DurableStoreEntries, OnDurableStoreChangedListener, DurableStoreOperation, DurableStoreChange } from '@luvio/environments';
2
+ import { DurableStorePersistence } from './durableStorePersistence';
2
3
  export declare class MockDurableStore implements DurableStore {
3
4
  listeners: Set<OnDurableStoreChangedListener>;
4
- segments: {
5
- [id: string]: DurableStoreEntries<unknown>;
6
- };
5
+ persistence: DurableStorePersistence;
6
+ constructor(persistence?: DurableStorePersistence);
7
7
  getEntries<T>(entryIds: string[], segment: string): Promise<DurableStoreEntries<T> | undefined>;
8
- getAllEntries<T>(segment: string): Promise<DurableStoreEntries<T> | undefined>;
8
+ getAllEntries<T>(segment: string): Promise<DurableStoreEntries<T>>;
9
9
  setEntries<T>(entries: DurableStoreEntries<T>, segment: string): Promise<void>;
10
10
  evictEntries(ids: string[], segment: string): Promise<void>;
11
11
  registerOnChangedListener(listener: OnDurableStoreChangedListener): () => Promise<void>;
@@ -0,0 +1,11 @@
1
+ export interface DurableStorePersistence {
2
+ get<T>(key: string): Promise<T | undefined>;
3
+ set<T>(key: string, value: T): Promise<void>;
4
+ delete(key: string): Promise<void>;
5
+ }
6
+ export declare class MemoryDurableStorePersistence implements DurableStorePersistence {
7
+ private store;
8
+ get<T>(key: string): Promise<T | undefined>;
9
+ set<T>(key: string, value: T): Promise<void>;
10
+ delete(key: string): Promise<void>;
11
+ }
@@ -3,3 +3,4 @@ export { verifyImmutable, isImmutable } from './verification';
3
3
  export { getMockLuvioWithFulfilledSnapshot, getMockFulfilledSnapshot } from './mocks';
4
4
  export { stripProperties } from './utils';
5
5
  export { MockDurableStore } from './durableStore';
6
+ export { MemoryDurableStorePersistence, DurableStorePersistence } from './durableStorePersistence';
@@ -1,10 +1,12 @@
1
1
  (function (global, factory) {
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('sinon'), require('@luvio/environments')) :
3
3
  typeof define === 'function' && define.amd ? define(['exports', 'sinon', '@luvio/environments'], factory) :
4
- (global = global || self, factory(global.luvioAdapterTestLibrary = {}, global.sinon, global.environments));
5
- }(this, (function (exports, sinon, environments) { 'use strict';
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.luvioAdapterTestLibrary = {}, global.sinon, global.environments));
5
+ })(this, (function (exports, sinon, environments) { 'use strict';
6
6
 
7
- sinon = sinon && Object.prototype.hasOwnProperty.call(sinon, 'default') ? sinon['default'] : sinon;
7
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
+
9
+ var sinon__default = /*#__PURE__*/_interopDefaultLegacy(sinon);
8
10
 
9
11
  /**
10
12
  * Clone an object
@@ -57,6 +59,7 @@
57
59
  }
58
60
 
59
61
  const networkConnectivityStateMap = new WeakMap();
62
+ exports.ConnectivityState = void 0;
60
63
  (function (ConnectivityState) {
61
64
  ConnectivityState[ConnectivityState["Online"] = 0] = "Online";
62
65
  ConnectivityState[ConnectivityState["Offline"] = 1] = "Offline";
@@ -100,7 +103,7 @@
100
103
  }
101
104
  function buildMockNetworkAdapter(mockPayloads) {
102
105
  // any endpoints not setup with a fake will return a rejected promise
103
- const networkAdapter = sinon.stub().rejects(buildMockSetupError());
106
+ const networkAdapter = sinon__default["default"].stub().rejects(buildMockSetupError());
104
107
  callCountMap.set(networkAdapter, 0);
105
108
  mockPayloadsMap.set(networkAdapter, mockPayloads);
106
109
  setMockNetworkPayloads(networkAdapter, mockPayloads);
@@ -136,7 +139,7 @@
136
139
  // sort mock payloads so least-specific network args are registered first
137
140
  mockPayloads.sort(sortPayloads).forEach((mockPayload) => {
138
141
  const { networkArgs, response } = mockPayload;
139
- const args = sinon.match(networkArgs);
142
+ const args = sinon__default["default"].match(networkArgs);
140
143
  stub.withArgs(args).callsFake(() => {
141
144
  return onNetworkStubCalled(stub, response);
142
145
  });
@@ -158,7 +161,7 @@
158
161
  function overrideMockNetworkResponses(mockNetworkAdapter, responses) {
159
162
  const stub = mockNetworkAdapter;
160
163
  let index = 0;
161
- stub.withArgs(sinon.match.any).callsFake(() => {
164
+ stub.withArgs(sinon__default["default"].match.any).callsFake(() => {
162
165
  const response = responses[index++];
163
166
  if (response === undefined) {
164
167
  // if they have more requests than expected
@@ -281,35 +284,51 @@
281
284
  return mockFulfilledSnapshot;
282
285
  }
283
286
 
284
- class MockDurableStore {
287
+ class MemoryDurableStorePersistence {
285
288
  constructor() {
289
+ this.store = {};
290
+ }
291
+ async get(key) {
292
+ return this.store[key];
293
+ }
294
+ async set(key, value) {
295
+ this.store[key] = value;
296
+ }
297
+ async delete(key) {
298
+ delete this.store[key];
299
+ }
300
+ }
301
+
302
+ class MockDurableStore {
303
+ constructor(persistence) {
304
+ // NOTE: This mock class doesn't enforce read/write synchronization
286
305
  this.listeners = new Set();
287
- this.segments = {};
306
+ this.persistence = persistence || new MemoryDurableStorePersistence();
288
307
  }
289
308
  getEntries(entryIds, segment) {
290
309
  const returnSource = Object.create(null);
291
- const entries = this.segments[segment];
292
- if (entries === undefined) {
293
- return Promise.resolve(undefined);
294
- }
295
- for (const entryId of entryIds) {
296
- const entry = entries[entryId];
297
- if (entry !== undefined) {
298
- returnSource[entryId] = clone(entry);
310
+ return this.persistence.get(segment).then((entries) => {
311
+ if (entries === undefined) {
312
+ return undefined;
299
313
  }
300
- }
301
- return Promise.resolve(returnSource);
314
+ for (const entryId of entryIds) {
315
+ const entry = entries[entryId];
316
+ if (entry !== undefined) {
317
+ returnSource[entryId] = clone(entry);
318
+ }
319
+ }
320
+ return returnSource;
321
+ });
302
322
  }
303
323
  getAllEntries(segment) {
304
324
  const returnSource = Object.create(null);
305
- let entries = this.segments[segment];
306
- if (entries === undefined) {
307
- entries = {};
308
- }
309
- for (const key of Object.keys(entries)) {
310
- returnSource[key] = clone(entries[key]);
311
- }
312
- return Promise.resolve(returnSource);
325
+ return this.persistence.get(segment).then((rawEntries) => {
326
+ const entries = rawEntries === undefined ? {} : rawEntries;
327
+ for (const key of Object.keys(entries)) {
328
+ returnSource[key] = clone(entries[key]);
329
+ }
330
+ return returnSource;
331
+ });
313
332
  }
314
333
  setEntries(entries, segment) {
315
334
  return this.batchOperations([
@@ -328,43 +347,39 @@
328
347
  return Promise.resolve();
329
348
  };
330
349
  }
331
- batchOperations(operations) {
332
- const allPromises = operations.map((operation) => {
333
- return this.performOperation(operation);
334
- });
335
- return Promise.all(allPromises).then((changes) => {
336
- // IMPORTANT - listeners are called after `.then` so it's on the next
337
- // tick
338
- this.listeners.forEach((listener) => {
339
- listener(changes);
340
- });
350
+ async batchOperations(operations) {
351
+ const changes = [];
352
+ for (let i = 0; i < operations.length; i++) {
353
+ changes.push(await this.performOperation(operations[i]));
354
+ }
355
+ this.listeners.forEach((listener) => {
356
+ listener(changes);
341
357
  });
342
358
  }
343
- performOperation(operation) {
359
+ async performOperation(operation) {
344
360
  const segment = operation.segment;
345
- let existingEntries = this.segments[segment];
346
- if (existingEntries === undefined) {
347
- existingEntries = {};
348
- }
349
- let ids;
361
+ const rawEntries = await this.persistence.get(segment);
362
+ const entries = rawEntries === undefined ? {} : rawEntries;
363
+ let ids = [];
350
364
  switch (operation.type) {
351
365
  case environments.DurableStoreOperationType.SetEntries:
352
366
  ids = Object.keys(operation.entries);
353
367
  ids.forEach((id) => {
354
- existingEntries[id] = clone(operation.entries[id]);
368
+ entries[id] = clone(operation.entries[id]);
355
369
  });
356
370
  break;
357
371
  case environments.DurableStoreOperationType.EvictEntries:
358
372
  ids = operation.ids;
359
373
  ids.forEach((id) => {
360
- delete existingEntries[id];
374
+ delete entries[id];
361
375
  });
362
376
  }
363
- this.segments[operation.segment] = existingEntries;
364
- return Promise.resolve({ ids, segment, type: operation.type });
377
+ await this.persistence.set(operation.segment, entries);
378
+ return { ids, segment, type: operation.type };
365
379
  }
366
380
  }
367
381
 
382
+ exports.MemoryDurableStorePersistence = MemoryDurableStorePersistence;
368
383
  exports.MockDurableStore = MockDurableStore;
369
384
  exports.buildErrorMockPayload = buildErrorMockPayload;
370
385
  exports.buildFetchResponse = buildFetchResponse;
@@ -383,4 +398,4 @@
383
398
 
384
399
  Object.defineProperty(exports, '__esModule', { value: true });
385
400
 
386
- })));
401
+ }));
@@ -1,11 +1,11 @@
1
1
  import { DurableStore, DurableStoreEntries, OnDurableStoreChangedListener, DurableStoreOperation, DurableStoreChange } from '@luvio/environments';
2
+ import { DurableStorePersistence } from './durableStorePersistence';
2
3
  export declare class MockDurableStore implements DurableStore {
3
4
  listeners: Set<OnDurableStoreChangedListener>;
4
- segments: {
5
- [id: string]: DurableStoreEntries<unknown>;
6
- };
5
+ persistence: DurableStorePersistence;
6
+ constructor(persistence?: DurableStorePersistence);
7
7
  getEntries<T>(entryIds: string[], segment: string): Promise<DurableStoreEntries<T> | undefined>;
8
- getAllEntries<T>(segment: string): Promise<DurableStoreEntries<T> | undefined>;
8
+ getAllEntries<T>(segment: string): Promise<DurableStoreEntries<T>>;
9
9
  setEntries<T>(entries: DurableStoreEntries<T>, segment: string): Promise<void>;
10
10
  evictEntries(ids: string[], segment: string): Promise<void>;
11
11
  registerOnChangedListener(listener: OnDurableStoreChangedListener): () => Promise<void>;
@@ -0,0 +1,11 @@
1
+ export interface DurableStorePersistence {
2
+ get<T>(key: string): Promise<T | undefined>;
3
+ set<T>(key: string, value: T): Promise<void>;
4
+ delete(key: string): Promise<void>;
5
+ }
6
+ export declare class MemoryDurableStorePersistence implements DurableStorePersistence {
7
+ private store;
8
+ get<T>(key: string): Promise<T | undefined>;
9
+ set<T>(key: string, value: T): Promise<void>;
10
+ delete(key: string): Promise<void>;
11
+ }
@@ -3,3 +3,4 @@ export { verifyImmutable, isImmutable } from './verification';
3
3
  export { getMockLuvioWithFulfilledSnapshot, getMockFulfilledSnapshot } from './mocks';
4
4
  export { stripProperties } from './utils';
5
5
  export { MockDurableStore } from './durableStore';
6
+ export { MemoryDurableStorePersistence, DurableStorePersistence } from './durableStorePersistence';
@@ -1,10 +1,12 @@
1
1
  (function (global, factory) {
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('sinon'), require('@luvio/environments')) :
3
3
  typeof define === 'function' && define.amd ? define(['exports', 'sinon', '@luvio/environments'], factory) :
4
- (global = global || self, factory(global.luvioAdapterTestLibrary = {}, global.sinon, global.environments));
5
- }(this, (function (exports, sinon, environments) { 'use strict';
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.luvioAdapterTestLibrary = {}, global.sinon, global.environments));
5
+ })(this, (function (exports, sinon, environments) { 'use strict';
6
6
 
7
- sinon = sinon && Object.prototype.hasOwnProperty.call(sinon, 'default') ? sinon['default'] : sinon;
7
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
+
9
+ var sinon__default = /*#__PURE__*/_interopDefaultLegacy(sinon);
8
10
 
9
11
  /**
10
12
  * Clone an object
@@ -57,6 +59,7 @@
57
59
  }
58
60
 
59
61
  var networkConnectivityStateMap = new WeakMap();
62
+ exports.ConnectivityState = void 0;
60
63
  (function (ConnectivityState) {
61
64
  ConnectivityState[ConnectivityState["Online"] = 0] = "Online";
62
65
  ConnectivityState[ConnectivityState["Offline"] = 1] = "Offline";
@@ -100,7 +103,7 @@
100
103
  }
101
104
  function buildMockNetworkAdapter(mockPayloads) {
102
105
  // any endpoints not setup with a fake will return a rejected promise
103
- var networkAdapter = sinon.stub().rejects(buildMockSetupError());
106
+ var networkAdapter = sinon__default["default"].stub().rejects(buildMockSetupError());
104
107
  callCountMap.set(networkAdapter, 0);
105
108
  mockPayloadsMap.set(networkAdapter, mockPayloads);
106
109
  setMockNetworkPayloads(networkAdapter, mockPayloads);
@@ -136,7 +139,7 @@
136
139
  // sort mock payloads so least-specific network args are registered first
137
140
  mockPayloads.sort(sortPayloads).forEach(function (mockPayload) {
138
141
  var networkArgs = mockPayload.networkArgs, response = mockPayload.response;
139
- var args = sinon.match(networkArgs);
142
+ var args = sinon__default["default"].match(networkArgs);
140
143
  stub.withArgs(args).callsFake(function () {
141
144
  return onNetworkStubCalled(stub, response);
142
145
  });
@@ -158,7 +161,7 @@
158
161
  function overrideMockNetworkResponses(mockNetworkAdapter, responses) {
159
162
  var stub = mockNetworkAdapter;
160
163
  var index = 0;
161
- stub.withArgs(sinon.match.any).callsFake(function () {
164
+ stub.withArgs(sinon__default["default"].match.any).callsFake(function () {
162
165
  var response = responses[index++];
163
166
  if (response === undefined) {
164
167
  // if they have more requests than expected
@@ -230,10 +233,10 @@
230
233
  throw new Error('IE11 does not throw when mutating a frozen object');
231
234
  }
232
235
  }) === false) {
233
- throw new Error("Unexpected mutable property found at " + path + ": Array is extensible!");
236
+ throw new Error("Unexpected mutable property found at ".concat(path, ": Array is extensible!"));
234
237
  }
235
238
  value.forEach(function (item, index) {
236
- verifyImmutable(item, path + "." + index);
239
+ verifyImmutable(item, "".concat(path, ".").concat(index));
237
240
  });
238
241
  return;
239
242
  }
@@ -243,7 +246,7 @@
243
246
  throw new Error('IE11 does not throw when mutating a frozen object');
244
247
  }
245
248
  }) === false) {
246
- throw new Error("Unexpected mutable property found at " + path + ": Object is extensible!");
249
+ throw new Error("Unexpected mutable property found at ".concat(path, ": Object is extensible!"));
247
250
  }
248
251
  Object.keys(value).forEach(function (key) {
249
252
  if (doesThrow(function () {
@@ -253,9 +256,9 @@
253
256
  throw new Error('IE11 does not throw when mutating a frozen object');
254
257
  }
255
258
  }) === false) {
256
- throw new Error("Unexpected mutable property found at " + path + ": \"" + path + "." + key + "\" is mutable!");
259
+ throw new Error("Unexpected mutable property found at ".concat(path, ": \"").concat(path, ".").concat(key, "\" is mutable!"));
257
260
  }
258
- verifyImmutable(value[key], path + "." + key);
261
+ verifyImmutable(value[key], "".concat(path, ".").concat(key));
259
262
  });
260
263
  }
261
264
 
@@ -286,37 +289,121 @@
286
289
  return mockFulfilledSnapshot;
287
290
  }
288
291
 
292
+ /*! *****************************************************************************
293
+ Copyright (c) Microsoft Corporation.
294
+
295
+ Permission to use, copy, modify, and/or distribute this software for any
296
+ purpose with or without fee is hereby granted.
297
+
298
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
299
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
300
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
301
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
302
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
303
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
304
+ PERFORMANCE OF THIS SOFTWARE.
305
+ ***************************************************************************** */
306
+
307
+ function __awaiter(thisArg, _arguments, P, generator) {
308
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
309
+ return new (P || (P = Promise))(function (resolve, reject) {
310
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
311
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
312
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
313
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
314
+ });
315
+ }
316
+
317
+ function __generator(thisArg, body) {
318
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
319
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
320
+ function verb(n) { return function (v) { return step([n, v]); }; }
321
+ function step(op) {
322
+ if (f) throw new TypeError("Generator is already executing.");
323
+ while (_) try {
324
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
325
+ if (y = 0, t) op = [op[0] & 2, t.value];
326
+ switch (op[0]) {
327
+ case 0: case 1: t = op; break;
328
+ case 4: _.label++; return { value: op[1], done: false };
329
+ case 5: _.label++; y = op[1]; op = [0]; continue;
330
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
331
+ default:
332
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
333
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
334
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
335
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
336
+ if (t[2]) _.ops.pop();
337
+ _.trys.pop(); continue;
338
+ }
339
+ op = body.call(thisArg, _);
340
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
341
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
342
+ }
343
+ }
344
+
345
+ var MemoryDurableStorePersistence = /** @class */ (function () {
346
+ function MemoryDurableStorePersistence() {
347
+ this.store = {};
348
+ }
349
+ MemoryDurableStorePersistence.prototype.get = function (key) {
350
+ return __awaiter(this, void 0, void 0, function () {
351
+ return __generator(this, function (_a) {
352
+ return [2 /*return*/, this.store[key]];
353
+ });
354
+ });
355
+ };
356
+ MemoryDurableStorePersistence.prototype.set = function (key, value) {
357
+ return __awaiter(this, void 0, void 0, function () {
358
+ return __generator(this, function (_a) {
359
+ this.store[key] = value;
360
+ return [2 /*return*/];
361
+ });
362
+ });
363
+ };
364
+ MemoryDurableStorePersistence.prototype.delete = function (key) {
365
+ return __awaiter(this, void 0, void 0, function () {
366
+ return __generator(this, function (_a) {
367
+ delete this.store[key];
368
+ return [2 /*return*/];
369
+ });
370
+ });
371
+ };
372
+ return MemoryDurableStorePersistence;
373
+ }());
374
+
289
375
  var MockDurableStore = /** @class */ (function () {
290
- function MockDurableStore() {
376
+ function MockDurableStore(persistence) {
377
+ // NOTE: This mock class doesn't enforce read/write synchronization
291
378
  this.listeners = new Set();
292
- this.segments = {};
379
+ this.persistence = persistence || new MemoryDurableStorePersistence();
293
380
  }
294
381
  MockDurableStore.prototype.getEntries = function (entryIds, segment) {
295
382
  var returnSource = Object.create(null);
296
- var entries = this.segments[segment];
297
- if (entries === undefined) {
298
- return Promise.resolve(undefined);
299
- }
300
- for (var _i = 0, entryIds_1 = entryIds; _i < entryIds_1.length; _i++) {
301
- var entryId = entryIds_1[_i];
302
- var entry = entries[entryId];
303
- if (entry !== undefined) {
304
- returnSource[entryId] = clone(entry);
383
+ return this.persistence.get(segment).then(function (entries) {
384
+ if (entries === undefined) {
385
+ return undefined;
305
386
  }
306
- }
307
- return Promise.resolve(returnSource);
387
+ for (var _i = 0, entryIds_1 = entryIds; _i < entryIds_1.length; _i++) {
388
+ var entryId = entryIds_1[_i];
389
+ var entry = entries[entryId];
390
+ if (entry !== undefined) {
391
+ returnSource[entryId] = clone(entry);
392
+ }
393
+ }
394
+ return returnSource;
395
+ });
308
396
  };
309
397
  MockDurableStore.prototype.getAllEntries = function (segment) {
310
398
  var returnSource = Object.create(null);
311
- var entries = this.segments[segment];
312
- if (entries === undefined) {
313
- entries = {};
314
- }
315
- for (var _i = 0, _a = Object.keys(entries); _i < _a.length; _i++) {
316
- var key = _a[_i];
317
- returnSource[key] = clone(entries[key]);
318
- }
319
- return Promise.resolve(returnSource);
399
+ return this.persistence.get(segment).then(function (rawEntries) {
400
+ var entries = rawEntries === undefined ? {} : rawEntries;
401
+ for (var _i = 0, _a = Object.keys(entries); _i < _a.length; _i++) {
402
+ var key = _a[_i];
403
+ returnSource[key] = clone(entries[key]);
404
+ }
405
+ return returnSource;
406
+ });
320
407
  };
321
408
  MockDurableStore.prototype.setEntries = function (entries, segment) {
322
409
  return this.batchOperations([
@@ -337,44 +424,70 @@
337
424
  };
338
425
  };
339
426
  MockDurableStore.prototype.batchOperations = function (operations) {
340
- var _this = this;
341
- var allPromises = operations.map(function (operation) {
342
- return _this.performOperation(operation);
343
- });
344
- return Promise.all(allPromises).then(function (changes) {
345
- // IMPORTANT - listeners are called after `.then` so it's on the next
346
- // tick
347
- _this.listeners.forEach(function (listener) {
348
- listener(changes);
427
+ return __awaiter(this, void 0, void 0, function () {
428
+ var changes, i, _a, _b;
429
+ return __generator(this, function (_c) {
430
+ switch (_c.label) {
431
+ case 0:
432
+ changes = [];
433
+ i = 0;
434
+ _c.label = 1;
435
+ case 1:
436
+ if (!(i < operations.length)) return [3 /*break*/, 4];
437
+ _b = (_a = changes).push;
438
+ return [4 /*yield*/, this.performOperation(operations[i])];
439
+ case 2:
440
+ _b.apply(_a, [_c.sent()]);
441
+ _c.label = 3;
442
+ case 3:
443
+ i++;
444
+ return [3 /*break*/, 1];
445
+ case 4:
446
+ this.listeners.forEach(function (listener) {
447
+ listener(changes);
448
+ });
449
+ return [2 /*return*/];
450
+ }
349
451
  });
350
452
  });
351
453
  };
352
454
  MockDurableStore.prototype.performOperation = function (operation) {
353
- var segment = operation.segment;
354
- var existingEntries = this.segments[segment];
355
- if (existingEntries === undefined) {
356
- existingEntries = {};
357
- }
358
- var ids;
359
- switch (operation.type) {
360
- case environments.DurableStoreOperationType.SetEntries:
361
- ids = Object.keys(operation.entries);
362
- ids.forEach(function (id) {
363
- existingEntries[id] = clone(operation.entries[id]);
364
- });
365
- break;
366
- case environments.DurableStoreOperationType.EvictEntries:
367
- ids = operation.ids;
368
- ids.forEach(function (id) {
369
- delete existingEntries[id];
370
- });
371
- }
372
- this.segments[operation.segment] = existingEntries;
373
- return Promise.resolve({ ids: ids, segment: segment, type: operation.type });
455
+ return __awaiter(this, void 0, void 0, function () {
456
+ var segment, rawEntries, entries, ids;
457
+ return __generator(this, function (_a) {
458
+ switch (_a.label) {
459
+ case 0:
460
+ segment = operation.segment;
461
+ return [4 /*yield*/, this.persistence.get(segment)];
462
+ case 1:
463
+ rawEntries = _a.sent();
464
+ entries = rawEntries === undefined ? {} : rawEntries;
465
+ ids = [];
466
+ switch (operation.type) {
467
+ case environments.DurableStoreOperationType.SetEntries:
468
+ ids = Object.keys(operation.entries);
469
+ ids.forEach(function (id) {
470
+ entries[id] = clone(operation.entries[id]);
471
+ });
472
+ break;
473
+ case environments.DurableStoreOperationType.EvictEntries:
474
+ ids = operation.ids;
475
+ ids.forEach(function (id) {
476
+ delete entries[id];
477
+ });
478
+ }
479
+ return [4 /*yield*/, this.persistence.set(operation.segment, entries)];
480
+ case 2:
481
+ _a.sent();
482
+ return [2 /*return*/, { ids: ids, segment: segment, type: operation.type }];
483
+ }
484
+ });
485
+ });
374
486
  };
375
487
  return MockDurableStore;
376
488
  }());
377
489
 
490
+ exports.MemoryDurableStorePersistence = MemoryDurableStorePersistence;
378
491
  exports.MockDurableStore = MockDurableStore;
379
492
  exports.buildErrorMockPayload = buildErrorMockPayload;
380
493
  exports.buildFetchResponse = buildFetchResponse;
@@ -393,4 +506,4 @@
393
506
 
394
507
  Object.defineProperty(exports, '__esModule', { value: true });
395
508
 
396
- })));
509
+ }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luvio/adapter-test-library",
3
- "version": "0.62.4",
3
+ "version": "0.63.3",
4
4
  "description": "Test library for luvio adapters",
5
5
  "main": "dist/umd/es2018/test-library.js",
6
6
  "module": "dist/es/es2018/test-library.js",
@@ -13,8 +13,8 @@
13
13
  "test": "jest"
14
14
  },
15
15
  "devDependencies": {
16
- "@luvio/engine": "0.62.4",
17
- "@luvio/environments": "0.62.4",
16
+ "@luvio/engine": "0.63.3",
17
+ "@luvio/environments": "0.63.3",
18
18
  "@types/sinon": "^7.5.2"
19
19
  },
20
20
  "dependencies": {
@@ -7,40 +7,48 @@ import {
7
7
  DurableStoreChange,
8
8
  } from '@luvio/environments';
9
9
  import { clone } from './utils';
10
+ import { DurableStorePersistence, MemoryDurableStorePersistence } from './durableStorePersistence';
10
11
  export class MockDurableStore implements DurableStore {
12
+ // NOTE: This mock class doesn't enforce read/write synchronization
13
+
11
14
  listeners = new Set<OnDurableStoreChangedListener>();
12
- segments: { [id: string]: DurableStoreEntries<unknown> } = {};
15
+ persistence: DurableStorePersistence;
16
+
17
+ constructor(persistence?: DurableStorePersistence) {
18
+ this.persistence = persistence || new MemoryDurableStorePersistence();
19
+ }
13
20
 
14
21
  getEntries<T>(
15
22
  entryIds: string[],
16
23
  segment: string
17
24
  ): Promise<DurableStoreEntries<T> | undefined> {
18
25
  const returnSource = Object.create(null);
19
- const entries = this.segments[segment];
20
-
21
- if (entries === undefined) {
22
- return Promise.resolve(undefined);
23
- }
26
+ return this.persistence.get<DurableStoreEntries<T>>(segment).then((entries) => {
27
+ if (entries === undefined) {
28
+ return undefined;
29
+ }
24
30
 
25
- for (const entryId of entryIds) {
26
- const entry = entries[entryId];
27
- if (entry !== undefined) {
28
- returnSource[entryId] = clone(entry);
31
+ for (const entryId of entryIds) {
32
+ const entry = entries[entryId];
33
+ if (entry !== undefined) {
34
+ returnSource[entryId] = clone(entry);
35
+ }
29
36
  }
30
- }
31
- return Promise.resolve(returnSource);
37
+ return returnSource;
38
+ });
32
39
  }
33
40
 
34
- getAllEntries<T>(segment: string): Promise<DurableStoreEntries<T> | undefined> {
41
+ getAllEntries<T>(segment: string): Promise<DurableStoreEntries<T>> {
35
42
  const returnSource = Object.create(null);
36
- let entries = this.segments[segment];
37
- if (entries === undefined) {
38
- entries = {};
39
- }
40
- for (const key of Object.keys(entries)) {
41
- returnSource[key] = clone(entries[key]);
42
- }
43
- return Promise.resolve(returnSource);
43
+
44
+ return this.persistence.get<DurableStoreEntries<T>>(segment).then((rawEntries) => {
45
+ const entries = rawEntries === undefined ? {} : rawEntries;
46
+
47
+ for (const key of Object.keys(entries)) {
48
+ returnSource[key] = clone(entries[key]);
49
+ }
50
+ return returnSource;
51
+ });
44
52
  }
45
53
 
46
54
  setEntries<T>(entries: DurableStoreEntries<T>, segment: string): Promise<void> {
@@ -63,43 +71,37 @@ export class MockDurableStore implements DurableStore {
63
71
  };
64
72
  }
65
73
 
66
- batchOperations<T>(operations: DurableStoreOperation<T>[]): Promise<void> {
67
- const allPromises = operations.map((operation) => {
68
- return this.performOperation(operation);
69
- });
74
+ async batchOperations<T>(operations: DurableStoreOperation<T>[]): Promise<void> {
75
+ const changes: DurableStoreChange[] = [];
76
+ for (let i = 0; i < operations.length; i++) {
77
+ changes.push(await this.performOperation(operations[i]));
78
+ }
70
79
 
71
- return Promise.all(allPromises).then((changes) => {
72
- // IMPORTANT - listeners are called after `.then` so it's on the next
73
- // tick
74
- this.listeners.forEach((listener) => {
75
- listener(changes);
76
- });
80
+ this.listeners.forEach((listener) => {
81
+ listener(changes);
77
82
  });
78
83
  }
79
84
 
80
- performOperation<T>(operation: DurableStoreOperation<T>): Promise<DurableStoreChange> {
85
+ async performOperation<T>(operation: DurableStoreOperation<T>): Promise<DurableStoreChange> {
81
86
  const segment = operation.segment;
82
- let existingEntries = this.segments[segment];
83
- if (existingEntries === undefined) {
84
- existingEntries = {};
85
- }
86
-
87
- let ids: string[];
87
+ const rawEntries = await this.persistence.get<DurableStoreEntries<T>>(segment);
88
+ const entries = rawEntries === undefined ? {} : rawEntries;
89
+ let ids: string[] = [];
88
90
  switch (operation.type) {
89
91
  case DurableStoreOperationType.SetEntries:
90
92
  ids = Object.keys(operation.entries);
91
93
  ids.forEach((id) => {
92
- existingEntries[id] = clone(operation.entries[id]);
94
+ entries[id] = clone(operation.entries[id]);
93
95
  });
94
96
  break;
95
97
  case DurableStoreOperationType.EvictEntries:
96
98
  ids = operation.ids;
97
99
  ids.forEach((id) => {
98
- delete existingEntries[id];
100
+ delete entries[id];
99
101
  });
100
102
  }
101
103
 
102
- this.segments[operation.segment] = existingEntries;
103
- return Promise.resolve({ ids, segment, type: operation.type });
104
+ await this.persistence.set(operation.segment, entries);
105
+ return { ids, segment, type: operation.type };
104
106
  }
105
107
  }
@@ -0,0 +1,21 @@
1
+ export interface DurableStorePersistence {
2
+ get<T>(key: string): Promise<T | undefined>;
3
+ set<T>(key: string, value: T): Promise<void>;
4
+ delete(key: string): Promise<void>;
5
+ }
6
+
7
+ export class MemoryDurableStorePersistence implements DurableStorePersistence {
8
+ private store: Record<string, any> = {};
9
+
10
+ async get<T>(key: string): Promise<T | undefined> {
11
+ return this.store[key];
12
+ }
13
+
14
+ async set<T>(key: string, value: T): Promise<void> {
15
+ this.store[key] = value;
16
+ }
17
+
18
+ async delete(key: string): Promise<void> {
19
+ delete this.store[key];
20
+ }
21
+ }
package/src/main.ts CHANGED
@@ -15,3 +15,4 @@ export { verifyImmutable, isImmutable } from './verification';
15
15
  export { getMockLuvioWithFulfilledSnapshot, getMockFulfilledSnapshot } from './mocks';
16
16
  export { stripProperties } from './utils';
17
17
  export { MockDurableStore } from './durableStore';
18
+ export { MemoryDurableStorePersistence, DurableStorePersistence } from './durableStorePersistence';