@procedures/store 0.3.0 → 0.5.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 +52 -0
- package/README.md +22 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/storage/api.d.ts +11 -0
- package/dist/storage/api.d.ts.map +1 -1
- package/dist/storage/api.js +36 -3
- package/dist/storage/api.js.map +1 -1
- package/dist/storage/hybrid.d.ts +49 -7
- package/dist/storage/hybrid.d.ts.map +1 -1
- package/dist/storage/hybrid.js +124 -36
- package/dist/storage/hybrid.js.map +1 -1
- package/dist/storage/synced-registry.d.ts +8 -1
- package/dist/storage/synced-registry.d.ts.map +1 -1
- package/dist/storage/synced-registry.js +25 -4
- package/dist/storage/synced-registry.js.map +1 -1
- package/package.json +3 -3
- package/src/storage/api.ts +35 -3
- package/src/storage/hybrid.ts +117 -33
- package/src/storage/synced-registry.ts +26 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
# @procedures/store
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 89481b0: A full pull of `HybridStorage` reads the local ids with `getIds()` of the local copy. Before, it read each local entry only for the ids, and `InMemoryStorage` copied each value (`structuredClone`) for it. A local copy without `getIds()` gives its entries, as before.
|
|
8
|
+
|
|
9
|
+
- `HybridStorage.getIds()` gives the ids of the local copy, or of the remote in `remote-only` mode.
|
|
10
|
+
- A new nightly benchmark measures a full pull of 1,000 items with and without `getIds()`. In one CI run, the mean time went from 15.3 ms to 10.7 ms.
|
|
11
|
+
- bc74091: `ApiStorage` and `HybridStorage` agree with the contract of `CollectionStorage`:
|
|
12
|
+
|
|
13
|
+
- `ApiStorage.get()` asks the procedure `collections.<name>.get` for `{ found, value }`. A stored `null` reads back as `null`. Before, it read back as `undefined`. A custom `service` or `get` operation gets the input `{ id }`, as before.
|
|
14
|
+
- `HybridStorage` takes a copy of each written value for the local copy, the queue and the remote. Before, a change of a value after a `set()` in the mode `write-back` changed the queued write.
|
|
15
|
+
- After `close()`, each operation of `ApiStorage` and `HybridStorage` rejects with an error that says "closed", and a second `close()` does nothing. `HybridStorage.close()` waits for the operations, the mode switch and the syncs that run. A `close()` before the first sync makes no remote call.
|
|
16
|
+
- After `close()`, `SyncedProcedureRegistry.register()` and `unregister()` change only the registry in memory, and a second `close()` does nothing. `close()` waits for the auto-sync that runs.
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [0f75644]
|
|
21
|
+
- Updated dependencies [09e5566]
|
|
22
|
+
- Updated dependencies [ab77f75]
|
|
23
|
+
- Updated dependencies [a47bee6]
|
|
24
|
+
- Updated dependencies [bc74091]
|
|
25
|
+
- Updated dependencies [bc74091]
|
|
26
|
+
- Updated dependencies [89481b0]
|
|
27
|
+
- @procedures/client@0.5.0
|
|
28
|
+
- @procedures/collections@0.5.0
|
|
29
|
+
|
|
30
|
+
## 0.4.0
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- 0abf2ec: The new test-only entry `@procedures/collections/testing` holds one contract suite for `CollectionStorage`: `describeCollectionStorageContract(name, { create, createWithMaxTombstones, copies, nullValues }, { describe, it })`. It tests the reads, the writes, the batches, the order of the entries, the JSON values, `getChangesSince` and its versions, `flush`, `getMetadata`, `close` and the errors. A random sequence of writes runs against a `Map`. The suite imports no test framework, so the runtime entries never load vitest. `InMemoryStorage`, `SqliteStorage`, `ApiStorage` and `HybridStorage` run it.
|
|
35
|
+
|
|
36
|
+
The suite found two differences, and the contract fixes them:
|
|
37
|
+
|
|
38
|
+
- An error of a `find` predicate of `InMemoryStorage` threw at once. Each method of a storage gives a promise, so each method of `InMemoryStorage` is now `async`, and an error is a rejected promise.
|
|
39
|
+
- `getMetadata().size` of `HybridStorage` was the size of the local copy, which `remote-only` keeps empty. It is now the result of `size()`. The new `stats.localSize` gives the size of the local copy.
|
|
40
|
+
- Updated dependencies [d919678]
|
|
41
|
+
- Updated dependencies [057d69a]
|
|
42
|
+
- Updated dependencies [b2a1a1e]
|
|
43
|
+
- Updated dependencies [057d69a]
|
|
44
|
+
- Updated dependencies [057d69a]
|
|
45
|
+
- Updated dependencies [057d69a]
|
|
46
|
+
- Updated dependencies [057d69a]
|
|
47
|
+
- Updated dependencies [057d69a]
|
|
48
|
+
- Updated dependencies [afd6a19]
|
|
49
|
+
- Updated dependencies [057d69a]
|
|
50
|
+
- Updated dependencies [0abf2ec]
|
|
51
|
+
- Updated dependencies [4e751da]
|
|
52
|
+
- @procedures/client@0.4.0
|
|
53
|
+
- @procedures/collections@0.4.0
|
|
54
|
+
|
|
3
55
|
## 0.3.0
|
|
4
56
|
|
|
5
57
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -81,6 +81,23 @@ These parts moved here from `@procedures/client` (roadmap 3.2):
|
|
|
81
81
|
|
|
82
82
|
An import of `@procedures/store/register` registers its procedures. An import of the package root registers nothing.
|
|
83
83
|
|
|
84
|
+
### The contract of `ApiStorage` and `HybridStorage`
|
|
85
|
+
|
|
86
|
+
The contract suite of `@procedures/collections/testing` tests `ApiStorage`, and `HybridStorage` in each mode. The two storages agree with `InMemoryStorage` and `SqliteStorage`:
|
|
87
|
+
|
|
88
|
+
- **Copies.** A change of a written or a read value does not change the stored item. `HybridStorage` takes a copy of each written value for the local copy, the queue and the remote. The values that `ApiStorage` sends and reads go through the transport.
|
|
89
|
+
- **`null`.** A stored `null` reads back as `null`. `ApiStorage.get()` sends `{ id, found: true }` to the procedure `collections.<name>.get`. The procedure then gives `{ found, value }` in one call.
|
|
90
|
+
- **The order of a delta.** `getChangesSince()` follows the order of the last change of each id.
|
|
91
|
+
- **The ids.** `HybridStorage.getIds()` gives the ids in the order of the entries. `ApiStorage` has no `getIds()`.
|
|
92
|
+
- **After `close()`.** Each operation rejects with an error whose message says "closed". A second `close()` does nothing.
|
|
93
|
+
|
|
94
|
+
Notes:
|
|
95
|
+
|
|
96
|
+
- A custom `service` or a custom `get` operation gets the input `{ id }`, as before. Its `null` reads back as `undefined`.
|
|
97
|
+
- A server before `found` ignores it and gives the item. Then a stored `null` reads back as `undefined`, as before.
|
|
98
|
+
- `HybridStorage.close()` waits for the operations, the switch and the syncs that run. Then it sends the queue, and it closes the remote and the local copy.
|
|
99
|
+
- `SyncedProcedureRegistry.close()` closes its storage. After it, `register()` and `unregister()` change only the registry in memory.
|
|
100
|
+
|
|
84
101
|
## The modes of `HybridStorage`
|
|
85
102
|
|
|
86
103
|
`HybridStorage` keeps a local copy of a remote collection storage. It has four modes, and `setMode()` changes the mode while the storage operates.
|
|
@@ -136,7 +153,9 @@ await users.setMode("write-through"); // The switch sends the queue, then syncs
|
|
|
136
153
|
- With a durable local copy, a new storage in `local-only` mode reads the items of the last run. It makes no remote call.
|
|
137
154
|
- Give a durable `queueStore` with a durable local copy. A restart applies the loaded queue to the local copy again, and the result does not change.
|
|
138
155
|
- The first sync after a restart reads all remote items. It removes each local item that the remote deleted and that no queued write changes.
|
|
139
|
-
- `
|
|
156
|
+
- A full sync reads the local ids with `getIds()` of the local copy. `InMemoryStorage` and `SqliteStorage` give the ids without a copy of the values. A local copy without `getIds()` gives its entries.
|
|
157
|
+
- `HybridStorage.getIds()` gives the ids of the local copy, or of the remote in `remote-only` mode.
|
|
158
|
+
- `close()` closes the local copy and the remote. A durable local copy keeps its items. A remote stays open when its own `close()` leaves it open, as `ApiStorage.close()` leaves the server.
|
|
140
159
|
|
|
141
160
|
```ts
|
|
142
161
|
import { ApiStorage, HybridStorage } from "@procedures/store";
|
|
@@ -164,6 +183,8 @@ const users = new HybridStorage(new ApiStorage(client, { collection: "users" }),
|
|
|
164
183
|
|
|
165
184
|
`ProcedureServer.useStorage(name, storage, { drain: true, close: true })` first starts `flush()` of the old storage. Then it uses the new storage and closes the old one. When the flush fails, the old storage stays.
|
|
166
185
|
|
|
186
|
+
`ProcedureServer.stop()` closes each storage one time and removes the storages from the server. A closed storage rejects each operation. Before the server starts again, give it new storages with `useStorage()`.
|
|
187
|
+
|
|
167
188
|
### The mode of a synced registry
|
|
168
189
|
|
|
169
190
|
`createSyncedRegistry({ type: "hybrid", client, mode })` takes the first mode. `setMode()` of the registry changes the mode of its storage.
|