@procedures/collections 0.2.3 → 0.4.0
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/CHANGELOG.md +22 -0
- package/README.md +32 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/interface.d.ts +42 -0
- package/dist/storage/interface.d.ts.map +1 -1
- package/dist/storage/interface.js.map +1 -1
- package/dist/storage/memory.d.ts +32 -1
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/storage/memory.js +111 -28
- package/dist/storage/memory.js.map +1 -1
- package/dist/testing/check.d.ts +27 -0
- package/dist/testing/check.d.ts.map +1 -0
- package/dist/testing/check.js +89 -0
- package/dist/testing/check.js.map +1 -0
- package/dist/testing/index.d.ts +10 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +10 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/storage-contract.d.ts +74 -0
- package/dist/testing/storage-contract.d.ts.map +1 -0
- package/dist/testing/storage-contract.js +405 -0
- package/dist/testing/storage-contract.js.map +1 -0
- package/package.json +5 -1
- package/src/storage/index.ts +2 -1
- package/src/storage/interface.ts +46 -0
- package/src/storage/memory.ts +124 -28
- package/src/testing/check.ts +86 -0
- package/src/testing/index.ts +19 -0
- package/src/testing/storage-contract.ts +509 -0
|
@@ -31,6 +31,21 @@ export interface CollectionStorage<T> {
|
|
|
31
31
|
* @returns Promise resolving to array of all items
|
|
32
32
|
*/
|
|
33
33
|
getAll(): Promise<T[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Every item with its id. A sync needs the ids: `getAll` gives only the values (roadmap R2).
|
|
36
|
+
* A storage that cannot give the ids does not have this method.
|
|
37
|
+
*
|
|
38
|
+
* @returns Promise resolving to the [id, item] pairs
|
|
39
|
+
*/
|
|
40
|
+
getEntries?(): Promise<Array<[string, T]>>;
|
|
41
|
+
/**
|
|
42
|
+
* The changes after a version (roadmap R28). A storage without a change log does not have
|
|
43
|
+
* this method, and a sync uses `getEntries()`.
|
|
44
|
+
*
|
|
45
|
+
* @param since - A `version` that an earlier call gave. Without it, the result has all items.
|
|
46
|
+
* @returns Promise resolving to the changed items, the deleted ids and the new version
|
|
47
|
+
*/
|
|
48
|
+
getChangesSince?(since?: string): Promise<StorageChanges<T>>;
|
|
34
49
|
/**
|
|
35
50
|
* Find items matching predicate.
|
|
36
51
|
*
|
|
@@ -93,6 +108,13 @@ export interface CollectionStorage<T> {
|
|
|
93
108
|
* @returns Promise resolving to Map of found items (missing IDs are omitted)
|
|
94
109
|
*/
|
|
95
110
|
getBatch(ids: string[]): Promise<Map<string, T>>;
|
|
111
|
+
/**
|
|
112
|
+
* This method sends the writes that wait in the storage to their destination (roadmap R28). A storage
|
|
113
|
+
* that keeps no writes does not have this method.
|
|
114
|
+
*
|
|
115
|
+
* @returns Promise resolving when the waiting writes reached their destination
|
|
116
|
+
*/
|
|
117
|
+
flush?(): Promise<void>;
|
|
96
118
|
/**
|
|
97
119
|
* Close storage and cleanup resources.
|
|
98
120
|
* Should be called when collection is no longer needed.
|
|
@@ -108,6 +130,26 @@ export interface CollectionStorage<T> {
|
|
|
108
130
|
*/
|
|
109
131
|
getMetadata?(): Promise<StorageMetadata>;
|
|
110
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* The changes of a storage after a version (roadmap R28).
|
|
135
|
+
*
|
|
136
|
+
* - `version` is opaque. The next call gives it back as `since`.
|
|
137
|
+
* - When `full` is true, `changed` has every item, and each id that it does not have was
|
|
138
|
+
* deleted. A storage gives a full result when it cannot find the changes since the version:
|
|
139
|
+
* the first call, a version of an older run, or a change log that dropped old deletes.
|
|
140
|
+
* - When `full` is false, `changed` has the items that changed after the version, and `deleted`
|
|
141
|
+
* has the ids that were deleted after it.
|
|
142
|
+
*/
|
|
143
|
+
export interface StorageChanges<T> {
|
|
144
|
+
/** The version of the storage that includes these changes. */
|
|
145
|
+
version: string;
|
|
146
|
+
/** True when `changed` has every item of the storage. */
|
|
147
|
+
full: boolean;
|
|
148
|
+
/** The items that changed, with their ids. */
|
|
149
|
+
changed: Array<[string, T]>;
|
|
150
|
+
/** The ids that were deleted. Empty when `full` is true. */
|
|
151
|
+
deleted: string[];
|
|
152
|
+
}
|
|
111
153
|
/**
|
|
112
154
|
* Optional storage metadata for monitoring.
|
|
113
155
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/storage/interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAKlC;;;;;OAKG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAExC;;;;OAIG;IACH,MAAM,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAEvB;;;;;OAKG;IACH,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAEpD;;;;;OAKG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAElC;;;;OAIG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAMxB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAErC;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAMvB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;;;;OAKG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IAMjD;;;;;OAKG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;;OAKG;IACH,WAAW,CAAC,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2BAA2B;IAC3B,IAAI,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAExD,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IAEb,6BAA6B;IAC7B,KAAK,CAAC,EAAE;QACN,iDAAiD;QACjD,OAAO,CAAC,EAAE,MAAM,CAAC;QAEjB,+CAA+C;QAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;QAElB,mDAAmD;QACnD,UAAU,CAAC,EAAE,MAAM,CAAC;QAEpB,iDAAiD;QACjD,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB,mBAAmB;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAEvE"}
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/storage/interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/storage/interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/storage/interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA4MH;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAI,KAAiB;IACzD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/storage/memory.d.ts
CHANGED
|
@@ -4,7 +4,16 @@
|
|
|
4
4
|
* Fast, volatile storage using JavaScript Map.
|
|
5
5
|
* All operations return Promises for interface consistency.
|
|
6
6
|
*/
|
|
7
|
-
import type { CollectionStorage, StorageMetadata } from "./interface.js";
|
|
7
|
+
import type { CollectionStorage, StorageChanges, StorageMetadata } from "./interface.js";
|
|
8
|
+
/** Options of an in-memory storage. */
|
|
9
|
+
export interface InMemoryStorageOptions {
|
|
10
|
+
/**
|
|
11
|
+
* The number of deletes that the change log keeps (roadmap R28). After more deletes, the log
|
|
12
|
+
* drops the oldest ones, and `getChangesSince` of an older version gives all items.
|
|
13
|
+
* @default 10000
|
|
14
|
+
*/
|
|
15
|
+
maxTombstones?: number;
|
|
16
|
+
}
|
|
8
17
|
/**
|
|
9
18
|
* In-memory storage backed by JavaScript Map.
|
|
10
19
|
*
|
|
@@ -13,6 +22,8 @@ import type { CollectionStorage, StorageMetadata } from "./interface.js";
|
|
|
13
22
|
* - No persistence (data lost on restart)
|
|
14
23
|
* - Memory-bound (limited by available RAM)
|
|
15
24
|
* - Returns Promises for API consistency with remote storage
|
|
25
|
+
* - Each error is a rejected promise: an error of a `find` predicate does not throw at once
|
|
26
|
+
* - A change log: `getChangesSince(version)` gives the changes after a version (roadmap R28)
|
|
16
27
|
*
|
|
17
28
|
* @example
|
|
18
29
|
* ```typescript
|
|
@@ -23,8 +34,24 @@ import type { CollectionStorage, StorageMetadata } from "./interface.js";
|
|
|
23
34
|
*/
|
|
24
35
|
export declare class InMemoryStorage<T> implements CollectionStorage<T> {
|
|
25
36
|
private data;
|
|
37
|
+
private epoch;
|
|
38
|
+
private seq;
|
|
39
|
+
/** The number of the last write of each id that has an item */
|
|
40
|
+
private readonly changedAt;
|
|
41
|
+
/** The number of the delete of each id that has no item, the oldest first (the tombstones) */
|
|
42
|
+
private readonly deletedAt;
|
|
43
|
+
/** The log does not know the deletes at or below this number: they were dropped */
|
|
44
|
+
private floor;
|
|
45
|
+
private readonly maxTombstones;
|
|
46
|
+
constructor(options?: InMemoryStorageOptions);
|
|
26
47
|
get(id: string): Promise<T | undefined>;
|
|
27
48
|
getAll(): Promise<T[]>;
|
|
49
|
+
getEntries(): Promise<Array<[string, T]>>;
|
|
50
|
+
/**
|
|
51
|
+
* The changes after a version (roadmap R28). A version of another storage, of a closed
|
|
52
|
+
* storage, or older than the dropped deletes gives all items (`full: true`).
|
|
53
|
+
*/
|
|
54
|
+
getChangesSince(since?: string): Promise<StorageChanges<T>>;
|
|
28
55
|
find(predicate: (item: T) => boolean): Promise<T[]>;
|
|
29
56
|
has(id: string): Promise<boolean>;
|
|
30
57
|
size(): Promise<number>;
|
|
@@ -64,5 +91,9 @@ export declare class InMemoryStorage<T> implements CollectionStorage<T> {
|
|
|
64
91
|
* Make storage iterable.
|
|
65
92
|
*/
|
|
66
93
|
[Symbol.iterator](): IterableIterator<[string, T]>;
|
|
94
|
+
private noteSet;
|
|
95
|
+
private noteDelete;
|
|
96
|
+
/** The number of a version of this storage, or undefined for another or an unknown version. */
|
|
97
|
+
private parseVersion;
|
|
67
98
|
}
|
|
68
99
|
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"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"}
|
package/dist/storage/memory.js
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
* Fast, volatile storage using JavaScript Map.
|
|
5
5
|
* All operations return Promises for interface consistency.
|
|
6
6
|
*/
|
|
7
|
+
/** A new epoch: a version of another storage, or of a closed one, does not match it. */
|
|
8
|
+
function newEpoch() {
|
|
9
|
+
return Math.random().toString(36).slice(2, 10);
|
|
10
|
+
}
|
|
7
11
|
/**
|
|
8
12
|
* In-memory storage backed by JavaScript Map.
|
|
9
13
|
*
|
|
@@ -12,6 +16,8 @@
|
|
|
12
16
|
* - No persistence (data lost on restart)
|
|
13
17
|
* - Memory-bound (limited by available RAM)
|
|
14
18
|
* - Returns Promises for API consistency with remote storage
|
|
19
|
+
* - Each error is a rejected promise: an error of a `find` predicate does not throw at once
|
|
20
|
+
* - A change log: `getChangesSince(version)` gives the changes after a version (roadmap R28)
|
|
15
21
|
*
|
|
16
22
|
* @example
|
|
17
23
|
* ```typescript
|
|
@@ -22,63 +28,107 @@
|
|
|
22
28
|
*/
|
|
23
29
|
export class InMemoryStorage {
|
|
24
30
|
data = new Map();
|
|
31
|
+
// The change log (roadmap R28). Each write gets the next number of `seq`. A version is
|
|
32
|
+
// `<epoch>:<seq>`.
|
|
33
|
+
epoch = newEpoch();
|
|
34
|
+
seq = 0;
|
|
35
|
+
/** The number of the last write of each id that has an item */
|
|
36
|
+
changedAt = new Map();
|
|
37
|
+
/** The number of the delete of each id that has no item, the oldest first (the tombstones) */
|
|
38
|
+
deletedAt = new Map();
|
|
39
|
+
/** The log does not know the deletes at or below this number: they were dropped */
|
|
40
|
+
floor = 0;
|
|
41
|
+
maxTombstones;
|
|
42
|
+
constructor(options = {}) {
|
|
43
|
+
this.maxTombstones = Math.max(0, options.maxTombstones ?? 10_000);
|
|
44
|
+
}
|
|
25
45
|
//
|
|
26
46
|
// ═══ Read Operations ═══
|
|
27
47
|
//
|
|
28
|
-
get(id) {
|
|
29
|
-
return
|
|
48
|
+
async get(id) {
|
|
49
|
+
return this.data.get(id);
|
|
30
50
|
}
|
|
31
|
-
getAll() {
|
|
32
|
-
return
|
|
51
|
+
async getAll() {
|
|
52
|
+
return Array.from(this.data.values());
|
|
33
53
|
}
|
|
34
|
-
|
|
54
|
+
async getEntries() {
|
|
55
|
+
return Array.from(this.data.entries());
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The changes after a version (roadmap R28). A version of another storage, of a closed
|
|
59
|
+
* storage, or older than the dropped deletes gives all items (`full: true`).
|
|
60
|
+
*/
|
|
61
|
+
async getChangesSince(since) {
|
|
62
|
+
const version = `${this.epoch}:${this.seq}`;
|
|
63
|
+
const from = this.parseVersion(since);
|
|
64
|
+
if (from === undefined || from < this.floor) {
|
|
65
|
+
return { version, full: true, changed: Array.from(this.data.entries()), deleted: [] };
|
|
66
|
+
}
|
|
67
|
+
const changed = [];
|
|
68
|
+
for (const [id, at] of this.changedAt) {
|
|
69
|
+
if (at > from)
|
|
70
|
+
changed.push([id, this.data.get(id)]);
|
|
71
|
+
}
|
|
72
|
+
const deleted = [];
|
|
73
|
+
for (const [id, at] of this.deletedAt) {
|
|
74
|
+
if (at > from)
|
|
75
|
+
deleted.push(id);
|
|
76
|
+
}
|
|
77
|
+
return { version, full: false, changed, deleted };
|
|
78
|
+
}
|
|
79
|
+
async find(predicate) {
|
|
35
80
|
const results = [];
|
|
36
81
|
for (const item of this.data.values()) {
|
|
37
82
|
if (predicate(item)) {
|
|
38
83
|
results.push(item);
|
|
39
84
|
}
|
|
40
85
|
}
|
|
41
|
-
return
|
|
86
|
+
return results;
|
|
42
87
|
}
|
|
43
|
-
has(id) {
|
|
44
|
-
return
|
|
88
|
+
async has(id) {
|
|
89
|
+
return this.data.has(id);
|
|
45
90
|
}
|
|
46
|
-
size() {
|
|
47
|
-
return
|
|
91
|
+
async size() {
|
|
92
|
+
return this.data.size;
|
|
48
93
|
}
|
|
49
94
|
//
|
|
50
95
|
// ═══ Write Operations ═══
|
|
51
96
|
//
|
|
52
|
-
set(id, value) {
|
|
97
|
+
async set(id, value) {
|
|
53
98
|
this.data.set(id, value);
|
|
54
|
-
|
|
99
|
+
this.noteSet(id);
|
|
55
100
|
}
|
|
56
|
-
delete(id) {
|
|
57
|
-
|
|
101
|
+
async delete(id) {
|
|
102
|
+
const existed = this.data.delete(id);
|
|
103
|
+
if (existed)
|
|
104
|
+
this.noteDelete(id);
|
|
105
|
+
return existed;
|
|
58
106
|
}
|
|
59
|
-
clear() {
|
|
107
|
+
async clear() {
|
|
108
|
+
for (const id of this.data.keys())
|
|
109
|
+
this.noteDelete(id);
|
|
60
110
|
this.data.clear();
|
|
61
|
-
return Promise.resolve();
|
|
62
111
|
}
|
|
63
112
|
//
|
|
64
113
|
// ═══ Bulk Operations ═══
|
|
65
114
|
//
|
|
66
|
-
setBatch(items) {
|
|
115
|
+
async setBatch(items) {
|
|
67
116
|
for (const [id, value] of items) {
|
|
68
117
|
this.data.set(id, value);
|
|
118
|
+
this.noteSet(id);
|
|
69
119
|
}
|
|
70
|
-
return Promise.resolve();
|
|
71
120
|
}
|
|
72
|
-
deleteBatch(ids) {
|
|
121
|
+
async deleteBatch(ids) {
|
|
73
122
|
let deleted = 0;
|
|
74
123
|
for (const id of ids) {
|
|
75
124
|
if (this.data.delete(id)) {
|
|
125
|
+
this.noteDelete(id);
|
|
76
126
|
deleted++;
|
|
77
127
|
}
|
|
78
128
|
}
|
|
79
|
-
return
|
|
129
|
+
return deleted;
|
|
80
130
|
}
|
|
81
|
-
getBatch(ids) {
|
|
131
|
+
async getBatch(ids) {
|
|
82
132
|
const result = new Map();
|
|
83
133
|
for (const id of ids) {
|
|
84
134
|
const value = this.data.get(id);
|
|
@@ -86,28 +136,33 @@ export class InMemoryStorage {
|
|
|
86
136
|
result.set(id, value);
|
|
87
137
|
}
|
|
88
138
|
}
|
|
89
|
-
return
|
|
139
|
+
return result;
|
|
90
140
|
}
|
|
91
141
|
//
|
|
92
142
|
// ═══ Lifecycle & Metadata ═══
|
|
93
143
|
//
|
|
94
|
-
close() {
|
|
144
|
+
async close() {
|
|
95
145
|
// No cleanup needed for in-memory storage
|
|
96
146
|
this.data.clear();
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
147
|
+
// A new epoch: a version of the closed storage gives all items
|
|
148
|
+
this.changedAt.clear();
|
|
149
|
+
this.deletedAt.clear();
|
|
150
|
+
this.epoch = newEpoch();
|
|
151
|
+
this.seq = 0;
|
|
152
|
+
this.floor = 0;
|
|
153
|
+
}
|
|
154
|
+
async getMetadata() {
|
|
100
155
|
// Rough memory estimation:
|
|
101
156
|
// Each entry has ~overhead of 100 bytes (key string + Map entry overhead)
|
|
102
157
|
const estimatedEntrySize = 100;
|
|
103
158
|
const memoryUsage = this.data.size * estimatedEntrySize;
|
|
104
|
-
return
|
|
159
|
+
return {
|
|
105
160
|
type: "memory",
|
|
106
161
|
size: this.data.size,
|
|
107
162
|
stats: {
|
|
108
163
|
memoryUsage,
|
|
109
164
|
},
|
|
110
|
-
}
|
|
165
|
+
};
|
|
111
166
|
}
|
|
112
167
|
//
|
|
113
168
|
// ═══ Additional Methods (Map compatibility) ═══
|
|
@@ -150,5 +205,33 @@ export class InMemoryStorage {
|
|
|
150
205
|
[Symbol.iterator]() {
|
|
151
206
|
return this.data.entries();
|
|
152
207
|
}
|
|
208
|
+
//
|
|
209
|
+
// ═══ The change log ═══
|
|
210
|
+
//
|
|
211
|
+
noteSet(id) {
|
|
212
|
+
this.changedAt.set(id, ++this.seq);
|
|
213
|
+
this.deletedAt.delete(id);
|
|
214
|
+
}
|
|
215
|
+
noteDelete(id) {
|
|
216
|
+
this.changedAt.delete(id);
|
|
217
|
+
// Delete, then set: the tombstone goes to the end of the order (the newest)
|
|
218
|
+
this.deletedAt.delete(id);
|
|
219
|
+
this.deletedAt.set(id, ++this.seq);
|
|
220
|
+
while (this.deletedAt.size > this.maxTombstones) {
|
|
221
|
+
const [oldest, at] = this.deletedAt.entries().next().value;
|
|
222
|
+
this.deletedAt.delete(oldest);
|
|
223
|
+
this.floor = Math.max(this.floor, at);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/** The number of a version of this storage, or undefined for another or an unknown version. */
|
|
227
|
+
parseVersion(since) {
|
|
228
|
+
if (since === undefined)
|
|
229
|
+
return undefined;
|
|
230
|
+
const separator = since.lastIndexOf(":");
|
|
231
|
+
if (separator < 0 || since.slice(0, separator) !== this.epoch)
|
|
232
|
+
return undefined;
|
|
233
|
+
const at = Number(since.slice(separator + 1));
|
|
234
|
+
return Number.isInteger(at) && at >= 0 && at <= this.seq ? at : undefined;
|
|
235
|
+
}
|
|
153
236
|
}
|
|
154
237
|
//# sourceMappingURL=memory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The checks of the contract suite. The suite does not import a test framework, so a runtime
|
|
3
|
+
* entry of this package never loads one. A failed check throws `ContractViolation`.
|
|
4
|
+
*/
|
|
5
|
+
/** The error of a failed check of the contract suite. */
|
|
6
|
+
export declare class ContractViolation extends Error {
|
|
7
|
+
readonly name = "ContractViolation";
|
|
8
|
+
}
|
|
9
|
+
/** This function gives the text of a value for a message: JSON, with a `Map` as its entries. */
|
|
10
|
+
export declare function show(value: unknown): string;
|
|
11
|
+
/**
|
|
12
|
+
* This function compares two values deeply: JSON values, arrays, plain objects and maps. Two maps
|
|
13
|
+
* are equal when they have the same keys with equal values, in any order.
|
|
14
|
+
*/
|
|
15
|
+
export declare function deepEqual(actual: unknown, expected: unknown): boolean;
|
|
16
|
+
/** This function throws `ContractViolation` when the two values are not deeply equal. */
|
|
17
|
+
export declare function same(actual: unknown, expected: unknown, what: string): void;
|
|
18
|
+
/** This function throws `ContractViolation` when the condition is false. */
|
|
19
|
+
export declare function holds(condition: boolean, what: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* This function starts an operation that must fail with a rejected promise, and gives the error.
|
|
22
|
+
* A synchronous throw breaks the contract too: each method of a storage gives a promise.
|
|
23
|
+
*/
|
|
24
|
+
export declare function rejects(start: () => Promise<unknown>, what: string): Promise<unknown>;
|
|
25
|
+
/** The entries sorted by id, for a comparison where the order is not part of the contract. */
|
|
26
|
+
export declare function byId<T>(entries: ReadonlyArray<readonly [string, T]>): Array<[string, T]>;
|
|
27
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/testing/check.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,yDAAyD;AACzD,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,SAAkB,IAAI,uBAAuB;CAC9C;AAED,gGAAgG;AAChG,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAO3C;AAQD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAkBrE;AAED,yFAAyF;AACzF,wBAAgB,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAI3E;AAED,4EAA4E;AAC5E,wBAAgB,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAc3F;AAED,8FAA8F;AAC9F,wBAAgB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAExF"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The checks of the contract suite. The suite does not import a test framework, so a runtime
|
|
3
|
+
* entry of this package never loads one. A failed check throws `ContractViolation`.
|
|
4
|
+
*/
|
|
5
|
+
/** The error of a failed check of the contract suite. */
|
|
6
|
+
export class ContractViolation extends Error {
|
|
7
|
+
name = "ContractViolation";
|
|
8
|
+
}
|
|
9
|
+
/** This function gives the text of a value for a message: JSON, with a `Map` as its entries. */
|
|
10
|
+
export function show(value) {
|
|
11
|
+
if (value === undefined)
|
|
12
|
+
return "undefined";
|
|
13
|
+
try {
|
|
14
|
+
return JSON.stringify(value, (_key, item) => (item instanceof Map ? { Map: [...item.entries()] } : item === undefined ? "<undefined>" : item));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return String(value);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function isPlainObject(value) {
|
|
21
|
+
if (typeof value !== "object" || value === null)
|
|
22
|
+
return false;
|
|
23
|
+
const prototype = Object.getPrototypeOf(value);
|
|
24
|
+
return prototype === Object.prototype || prototype === null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* This function compares two values deeply: JSON values, arrays, plain objects and maps. Two maps
|
|
28
|
+
* are equal when they have the same keys with equal values, in any order.
|
|
29
|
+
*/
|
|
30
|
+
export function deepEqual(actual, expected) {
|
|
31
|
+
if (Object.is(actual, expected))
|
|
32
|
+
return true;
|
|
33
|
+
if (actual instanceof Map && expected instanceof Map) {
|
|
34
|
+
if (actual.size !== expected.size)
|
|
35
|
+
return false;
|
|
36
|
+
for (const [key, value] of actual) {
|
|
37
|
+
if (!expected.has(key) || !deepEqual(value, expected.get(key)))
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
if (Array.isArray(actual) && Array.isArray(expected)) {
|
|
43
|
+
return actual.length === expected.length && actual.every((item, index) => deepEqual(item, expected[index]));
|
|
44
|
+
}
|
|
45
|
+
if (isPlainObject(actual) && isPlainObject(expected)) {
|
|
46
|
+
const keys = Object.keys(actual);
|
|
47
|
+
if (keys.length !== Object.keys(expected).length)
|
|
48
|
+
return false;
|
|
49
|
+
return keys.every((key) => Object.prototype.hasOwnProperty.call(expected, key) && deepEqual(actual[key], expected[key]));
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
/** This function throws `ContractViolation` when the two values are not deeply equal. */
|
|
54
|
+
export function same(actual, expected, what) {
|
|
55
|
+
if (!deepEqual(actual, expected)) {
|
|
56
|
+
throw new ContractViolation(`${what}: expected ${show(expected)}, got ${show(actual)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** This function throws `ContractViolation` when the condition is false. */
|
|
60
|
+
export function holds(condition, what) {
|
|
61
|
+
if (!condition)
|
|
62
|
+
throw new ContractViolation(what);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* This function starts an operation that must fail with a rejected promise, and gives the error.
|
|
66
|
+
* A synchronous throw breaks the contract too: each method of a storage gives a promise.
|
|
67
|
+
*/
|
|
68
|
+
export async function rejects(start, what) {
|
|
69
|
+
let promise;
|
|
70
|
+
try {
|
|
71
|
+
promise = start();
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
throw new ContractViolation(`${what}: the method threw at once (${show(error instanceof Error ? error.message : error)}), and did not give a rejected promise`);
|
|
75
|
+
}
|
|
76
|
+
holds(typeof promise?.then === "function", `${what}: the method did not give a promise`);
|
|
77
|
+
try {
|
|
78
|
+
await promise;
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
return error;
|
|
82
|
+
}
|
|
83
|
+
throw new ContractViolation(`${what}: the promise did not reject`);
|
|
84
|
+
}
|
|
85
|
+
/** The entries sorted by id, for a comparison where the order is not part of the contract. */
|
|
86
|
+
export function byId(entries) {
|
|
87
|
+
return [...entries].map(([id, value]) => [id, value]).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/testing/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@procedures/collections/testing`: the test-only entry of this package.
|
|
3
|
+
*
|
|
4
|
+
* This entry holds the contract suite of `CollectionStorage`. A storage package runs it in its
|
|
5
|
+
* tests with a factory of its storage. The entry imports no test framework: the caller gives
|
|
6
|
+
* `describe` and `it`. The runtime entries of the package do not import this entry.
|
|
7
|
+
*/
|
|
8
|
+
export { collectionStorageContract, describeCollectionStorageContract, type CollectionStorageContractOptions, type ContractCase, type ContractItem, type ContractStorage, type ContractTestApi, type ContractTestContext, } from "./storage-contract.js";
|
|
9
|
+
export { ContractViolation, deepEqual } from "./check.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,yBAAyB,EACzB,iCAAiC,EACjC,KAAK,gCAAgC,EACrC,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,mBAAmB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@procedures/collections/testing`: the test-only entry of this package.
|
|
3
|
+
*
|
|
4
|
+
* This entry holds the contract suite of `CollectionStorage`. A storage package runs it in its
|
|
5
|
+
* tests with a factory of its storage. The entry imports no test framework: the caller gives
|
|
6
|
+
* `describe` and `it`. The runtime entries of the package do not import this entry.
|
|
7
|
+
*/
|
|
8
|
+
export { collectionStorageContract, describeCollectionStorageContract, } from "./storage-contract.js";
|
|
9
|
+
export { ContractViolation, deepEqual } from "./check.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,yBAAyB,EACzB,iCAAiC,GAOlC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contract of `CollectionStorage` as one test suite (finding of roadmap R45).
|
|
3
|
+
*
|
|
4
|
+
* Each storage package runs the suite with a factory of its storage: `InMemoryStorage` in this
|
|
5
|
+
* package, `ApiStorage` and `HybridStorage` in `@procedures/store`, and `SqliteStorage` in
|
|
6
|
+
* `@procedures/sqlite`. Before, each package copied the cases of `InMemoryStorage`.
|
|
7
|
+
*
|
|
8
|
+
* The suite is in the test-only entry `@procedures/collections/testing`. It imports no test
|
|
9
|
+
* framework: the caller gives `describe` and `it`, and the checks throw `ContractViolation`. So a
|
|
10
|
+
* storage package imports the suite without a cycle, and a runtime entry never loads vitest.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { describe, it } from "vitest";
|
|
14
|
+
* import { describeCollectionStorageContract } from "@procedures/collections/testing";
|
|
15
|
+
*
|
|
16
|
+
* describeCollectionStorageContract("MyStorage", { create: () => new MyStorage() }, { describe, it });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import type { CollectionStorage } from "../storage/interface.js";
|
|
20
|
+
/** The item of the suite. Its `id` is its key, so a `HybridStorage` can sync it. */
|
|
21
|
+
export interface ContractItem {
|
|
22
|
+
id: string;
|
|
23
|
+
n: number;
|
|
24
|
+
tags?: string[];
|
|
25
|
+
}
|
|
26
|
+
/** A storage of the suite. */
|
|
27
|
+
export type ContractStorage = CollectionStorage<ContractItem>;
|
|
28
|
+
/** The options of the suite: the factory of the storage, and what the storage keeps. */
|
|
29
|
+
export interface CollectionStorageContractOptions {
|
|
30
|
+
/** This function makes a new, empty storage for each case. The case closes it at its end. */
|
|
31
|
+
create(): ContractStorage | Promise<ContractStorage>;
|
|
32
|
+
/**
|
|
33
|
+
* This function makes a new, empty storage whose change log keeps at most `max` deletes. With it,
|
|
34
|
+
* the suite tests the drop of the old deletes. A storage without such a limit does not give it.
|
|
35
|
+
*/
|
|
36
|
+
createWithMaxTombstones?: ((max: number) => ContractStorage | Promise<ContractStorage>) | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* True when the storage keeps a copy of each value: a change of a value after `set`, or of a read
|
|
39
|
+
* value, does not change the stored item. The interface does not ask for copies, so the default
|
|
40
|
+
* is false, and the suite then does not test them.
|
|
41
|
+
*/
|
|
42
|
+
copies?: boolean | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* False when a stored `null` reads back as `undefined`. A remote storage can lose the difference
|
|
45
|
+
* on the wire. The default is true.
|
|
46
|
+
*/
|
|
47
|
+
nullValues?: boolean | undefined;
|
|
48
|
+
}
|
|
49
|
+
/** The context that a test framework gives to a case. Vitest gives `skip`. */
|
|
50
|
+
export interface ContractTestContext {
|
|
51
|
+
skip?(note?: string): void;
|
|
52
|
+
}
|
|
53
|
+
/** One case of the suite. */
|
|
54
|
+
export interface ContractCase {
|
|
55
|
+
readonly name: string;
|
|
56
|
+
run(context?: ContractTestContext): Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
/** The functions of a test framework that the suite uses: `describe` and `it` of vitest fit. */
|
|
59
|
+
export interface ContractTestApi {
|
|
60
|
+
describe(name: string, body: () => void): unknown;
|
|
61
|
+
it(name: string, body: (context: ContractTestContext) => Promise<void>): unknown;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* This function gives the cases of the contract for a storage. Each case makes its own storage
|
|
65
|
+
* with `options.create`. A case for an optional method (`getEntries`, `getChangesSince`, `flush`,
|
|
66
|
+
* `getMetadata`) skips a storage without the method.
|
|
67
|
+
*/
|
|
68
|
+
export declare function collectionStorageContract(options: CollectionStorageContractOptions): ContractCase[];
|
|
69
|
+
/**
|
|
70
|
+
* This function declares the suite in a test framework: one `describe` with one `it` for each
|
|
71
|
+
* case. Vitest gives `skip` to a case, so a case for a missing optional method shows as skipped.
|
|
72
|
+
*/
|
|
73
|
+
export declare function describeCollectionStorageContract(name: string, options: CollectionStorageContractOptions, api: ContractTestApi): void;
|
|
74
|
+
//# sourceMappingURL=storage-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-contract.d.ts","sourceRoot":"","sources":["../../src/testing/storage-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,yBAAyB,CAAC;AAGjF,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,8BAA8B;AAC9B,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;AAE9D,wFAAwF;AACxF,MAAM,WAAW,gCAAgC;IAC/C,6FAA6F;IAC7F,MAAM,IAAI,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACrD;;;OAGG;IACH,uBAAuB,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,GAAG,SAAS,CAAC;IACpG;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED,8EAA8E;AAC9E,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,6BAA6B;AAC7B,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAED,gGAAgG;AAChG,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IAClD,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;CAClF;AAyCD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gCAAgC,GAAG,YAAY,EAAE,CA6XnG;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gCAAgC,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAMrI"}
|