@procedures/collections 0.4.0 → 0.6.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 +20 -0
- package/README.md +28 -10
- package/dist/.tsbuildinfo +1 -1
- package/dist/storage/interface.d.ts +25 -4
- package/dist/storage/interface.d.ts.map +1 -1
- package/dist/storage/interface.js.map +1 -1
- package/dist/storage/memory.d.ts +38 -7
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/storage/memory.js +79 -25
- package/dist/storage/memory.js.map +1 -1
- package/dist/testing/check.d.ts +0 -2
- package/dist/testing/check.d.ts.map +1 -1
- package/dist/testing/check.js +0 -4
- package/dist/testing/check.js.map +1 -1
- package/dist/testing/storage-contract.d.ts +11 -15
- package/dist/testing/storage-contract.d.ts.map +1 -1
- package/dist/testing/storage-contract.js +167 -45
- package/dist/testing/storage-contract.js.map +1 -1
- package/package.json +1 -1
- package/src/storage/interface.ts +26 -4
- package/src/storage/memory.ts +95 -26
- package/src/testing/check.ts +0 -5
- package/src/testing/storage-contract.ts +174 -60
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @procedures/collections
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
No changes in this release.
|
|
6
|
+
|
|
7
|
+
## 0.5.0
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- bc74091: The storages agree on the contract of `CollectionStorage`. `InMemoryStorage` changes in three points:
|
|
12
|
+
|
|
13
|
+
- It keeps copies. Each write takes a copy of the value (`structuredClone`), and each read gives a new copy. Before, it kept the values themselves. The option `copies: false` gives the old behavior for a caller that changes no value.
|
|
14
|
+
- A delta of `getChangesSince` follows the order of the last change of each id. Before, it followed the first write of each id.
|
|
15
|
+
- After `close()`, each operation rejects with an error that says "closed", and a second `close()` does nothing. Before, `close()` emptied the storage, and the storage kept working.
|
|
16
|
+
|
|
17
|
+
The contract suite of `@procedures/collections/testing` has no options `copies` and `nullValues` now. It tests the copies, a stored `null`, the order of each delta and the operations after `close()` for each storage. The helper `byId` is removed.
|
|
18
|
+
- 89481b0: The contract of `CollectionStorage` has the optional method `getIds()`. It gives the ids in the order of the entries, and it does not read or copy the values.
|
|
19
|
+
|
|
20
|
+
- `InMemoryStorage.getIds()` gives the keys of its map, without a `structuredClone` of the values.
|
|
21
|
+
- The contract suite of `@procedures/collections/testing` tests `getIds()`: the order, a new array for each call, the ids of `getEntries()`, and the rejection after `close()`. A storage without `getIds()` skips the case.
|
|
22
|
+
|
|
3
23
|
## 0.4.0
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -85,6 +85,9 @@ interface CollectionStorage<T> {
|
|
|
85
85
|
// Read Operations
|
|
86
86
|
get(id: string): Promise<T | undefined>;
|
|
87
87
|
getAll(): Promise<T[]>;
|
|
88
|
+
getEntries?(): Promise<Array<[string, T]>>;
|
|
89
|
+
getIds?(): Promise<string[]>;
|
|
90
|
+
getChangesSince?(since?: string): Promise<StorageChanges<T>>;
|
|
88
91
|
find(predicate: (item: T) => boolean): Promise<T[]>;
|
|
89
92
|
has(id: string): Promise<boolean>;
|
|
90
93
|
size(): Promise<number>;
|
|
@@ -105,6 +108,15 @@ interface CollectionStorage<T> {
|
|
|
105
108
|
}
|
|
106
109
|
```
|
|
107
110
|
|
|
111
|
+
Each storage agrees on these points:
|
|
112
|
+
|
|
113
|
+
- A storage keeps a copy of each value that a write takes, and each read gives a new copy. A change of a written or a read value does not change the stored item.
|
|
114
|
+
- A stored `null` reads back as `null`. A missing id reads back as `undefined`.
|
|
115
|
+
- The entries keep the order of the first set of each id, as a `Map` does.
|
|
116
|
+
- A delta of `getChangesSince` follows the order of the last change of each id. A full result follows the order of the entries.
|
|
117
|
+
- `getIds()` gives the ids in the order of the entries, and it does not read or copy the values. A storage that cannot give the ids cheaply does not have it. `HybridStorage` uses it for a full sync.
|
|
118
|
+
- After `close()`, each operation rejects with an error whose message says "closed". A second `close()` does nothing.
|
|
119
|
+
|
|
108
120
|
### The contract suite: `@procedures/collections/testing`
|
|
109
121
|
|
|
110
122
|
The test-only entry `@procedures/collections/testing` holds one test suite for the contract of `CollectionStorage`. A storage runs it with a factory:
|
|
@@ -118,39 +130,45 @@ describeCollectionStorageContract(
|
|
|
118
130
|
{
|
|
119
131
|
create: () => new MyStorage<ContractItem>(),
|
|
120
132
|
createWithMaxTombstones: (max) => new MyStorage<ContractItem>({ maxTombstones: max }),
|
|
121
|
-
copies: true,
|
|
122
133
|
},
|
|
123
134
|
{ describe, it },
|
|
124
135
|
);
|
|
125
136
|
```
|
|
126
137
|
|
|
127
|
-
- The suite tests the reads, the writes and the batches, the order of the entries, the results as new arrays
|
|
138
|
+
- The suite tests the reads, the writes and the batches, the order of the entries, `getIds`, and the results as new arrays.
|
|
139
|
+
- It tests the copies, the JSON values with `null`, and the writes at the same time.
|
|
140
|
+
- It tests `getChangesSince` with its versions and its order, `flush`, `getMetadata`, `close` and the errors.
|
|
128
141
|
- A case for an optional method skips a storage without the method.
|
|
129
|
-
- A random sequence of writes runs against a `Map
|
|
142
|
+
- A random sequence of writes runs against a `Map`. Each saved version must give the right changes, in the order of the last change of each id.
|
|
130
143
|
- The suite imports no test framework. The caller gives `describe` and `it`, and a failed check throws `ContractViolation`. The runtime entries do not import this entry.
|
|
131
|
-
-
|
|
144
|
+
- The suite has no option that hides a difference of a storage. Before, the options `copies` and `nullValues` declared the differences, and the suite sorted each delta.
|
|
132
145
|
|
|
133
146
|
| Storage | Package | Notes |
|
|
134
147
|
|---|---|---|
|
|
135
|
-
| `InMemoryStorage` | `@procedures/collections` | It
|
|
136
|
-
| `SqliteStorage` (in memory and in a file) | `@procedures/sqlite` | It gives copies. |
|
|
137
|
-
| `ApiStorage` | `@procedures/store` |
|
|
148
|
+
| `InMemoryStorage` | `@procedures/collections` | It copies with `structuredClone`. The run with `copies: false` skips only the case of the copies. |
|
|
149
|
+
| `SqliteStorage` (each engine, in memory and in a file) | `@procedures/sqlite` | It keeps JSON text, so it gives copies. |
|
|
150
|
+
| `ApiStorage` | `@procedures/store` | It reads `{ found, value }` from the procedure `get`, so a stored `null` stays `null`. It has no `getIds`. |
|
|
138
151
|
| `HybridStorage` (each mode, and a queue in IndexedDB) | `@procedures/store` | It has no `getChangesSince`. |
|
|
139
152
|
|
|
140
153
|
## Storage Backends
|
|
141
154
|
|
|
142
|
-
###
|
|
155
|
+
### InMemoryStorage
|
|
143
156
|
|
|
144
157
|
Fast, in-memory storage using JavaScript Map:
|
|
145
158
|
|
|
146
159
|
```typescript
|
|
147
|
-
import {
|
|
160
|
+
import { InMemoryStorage } from "@procedures/collections";
|
|
148
161
|
|
|
149
|
-
const storage = new
|
|
162
|
+
const storage = new InMemoryStorage<User>();
|
|
150
163
|
await storage.set("user-1", { name: "Alice", age: 30 });
|
|
151
164
|
const user = await storage.get("user-1");
|
|
152
165
|
```
|
|
153
166
|
|
|
167
|
+
- The storage keeps a copy of each written value, and each read gives a new copy (`structuredClone`). A `Date` stays a `Date`. A function in a value makes the write reject.
|
|
168
|
+
- The option `copies: false` turns the copies off: the storage keeps the values themselves, and the reads give them. It is faster. Give it only when no caller changes a value after a write or a read.
|
|
169
|
+
- `getIds()` gives the ids without a copy of the values.
|
|
170
|
+
- `close()` drops the items. After it, each operation rejects, and the methods of the `Map` interface (`keys()`, `values()`, `entries()`, `forEach()`) throw.
|
|
171
|
+
|
|
154
172
|
### ApiStorage
|
|
155
173
|
|
|
156
174
|
Remote storage via RPC client:
|