@procedures/store 0.47.1 → 0.47.2
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 +24 -13
- package/README.md +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/storage/feed.d.ts +3 -3
- package/dist/storage/feed.js +1 -1
- package/dist/storage/hybrid.d.ts +10 -10
- package/dist/storage/hybrid.d.ts.map +1 -1
- package/dist/storage/hybrid.js +8 -8
- package/dist/storage/hybrid.js.map +1 -1
- package/package.json +4 -4
- package/src/storage/feed.ts +3 -3
- package/src/storage/hybrid.ts +12 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @procedures/store
|
|
2
2
|
|
|
3
|
+
## 0.47.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [0650616]
|
|
8
|
+
- Updated dependencies [2684531]
|
|
9
|
+
- Updated dependencies [ae1e3fd]
|
|
10
|
+
- Updated dependencies [f1ece74]
|
|
11
|
+
- @procedures/client@0.47.2
|
|
12
|
+
- @procedures/collections@0.47.2
|
|
13
|
+
|
|
3
14
|
## 0.47.1
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
@@ -111,9 +122,9 @@
|
|
|
111
122
|
Migration steps:
|
|
112
123
|
|
|
113
124
|
- The site: no step. It does not catch a `TIMEOUT` of a `HybridStorage` write.
|
|
114
|
-
-
|
|
115
|
-
-
|
|
116
|
-
-
|
|
125
|
+
- An app: no step, unless code catches a `TIMEOUT` of a `write-through` write to show an undo. That code gets `PendingWriteError`, with the `TIMEOUT` as its `cause`.
|
|
126
|
+
- An app: the own `isUnavailable` that keeps `TIMEOUT` in the queue is not necessary at this time. Remove it, or keep it: the result is the same.
|
|
127
|
+
- An app: no step. To keep the old behavior, pass `isUnavailable: (error) => error?.retryable === true || error?.code === undefined`.
|
|
117
128
|
|
|
118
129
|
### Patch Changes
|
|
119
130
|
|
|
@@ -216,8 +227,8 @@
|
|
|
216
227
|
- A host whose `expose`, policy or limit pattern names such a path in text uses the encoded form, for example `collections.e2e%2Etabs.*`.
|
|
217
228
|
- An `mcpExclude` entry, an `expose` deny entry or a limit entry in the old raw form, for example `collections.e2e.tabs.drop`, does not match. The check compares the encoded key, so the procedure becomes visible, or the limit does not apply. Write each such entry in the encoded form, for example `collections.e2e%2Etabs.drop`.
|
|
218
229
|
- A subscriber of a dotted collection uses `collectionChangeTopic(name)`. The raw topic `collections.a.b` is the topic of the partition `b` of `a`.
|
|
219
|
-
-
|
|
220
|
-
-
|
|
230
|
+
- An app: read the collection of a topic with `collectionTopicPartition(topic)`, not with a pattern, for example `/^collections\.([^.]+)\./`.
|
|
231
|
+
- Other apps: no change, if their collection names have no `.` and no `%`.
|
|
221
232
|
|
|
222
233
|
### Patch Changes
|
|
223
234
|
|
|
@@ -234,7 +245,7 @@
|
|
|
234
245
|
|
|
235
246
|
Migration:
|
|
236
247
|
|
|
237
|
-
-
|
|
248
|
+
- Apps: no change at this time. The deprecated names work until the next MINOR.
|
|
238
249
|
- Before the next MINOR, replace `zodAdapter<T>(schema)` with `schema`. To keep the check of a schema against a type, write `const schema: z.ZodType<T> = ...`.
|
|
239
250
|
- Before the next MINOR, replace `typedAnySchema<T>()` and `outputSchema<T>()` with `typed<T>()`.
|
|
240
251
|
- A parse-only object (`{ parse }`) in `zodAdapter` becomes a Standard Schema with a `~standard` property.
|
|
@@ -371,7 +382,7 @@
|
|
|
371
382
|
|
|
372
383
|
### Patch Changes
|
|
373
384
|
|
|
374
|
-
- b7a5167: Added: the option `aroundRemoteApply` of `HybridStorage` puts each apply of the remote changes inside a hook
|
|
385
|
+
- b7a5167: Added: the option `aroundRemoteApply` of `HybridStorage` puts each apply of the remote changes inside a hook. An app uses it to start a span of a trace with the `traceparent` that the server sends with a change.
|
|
375
386
|
|
|
376
387
|
- `aroundRemoteApply(hint, apply, context)` starts `apply` one time and gives back its promise. `context.cause` is `"delta"`, `"hint"`, `"gap"` or `"pull"`. `context.hints` has the hints of the apply.
|
|
377
388
|
- A delta and a hint of the feed give their hint. A gap and a pull of the storage (the timer of `pullInterval`, `syncFromRemote()`, `sync()` and the first sync) give the hint `undefined`.
|
|
@@ -626,9 +637,9 @@
|
|
|
626
637
|
Migration:
|
|
627
638
|
|
|
628
639
|
- **Site.** No change. The site does not write collections.
|
|
629
|
-
- **
|
|
630
|
-
- **
|
|
631
|
-
- **
|
|
640
|
+
- **An app with `HybridStorage`.** No change for a storage or a `HybridStorage` without `versionOf`. A `HybridStorage` with `versionOf` over `ApiStorage` needs a server storage with the same `versionOf` (for example `new InMemoryStorage({ versionOf })`), or the option `sendBaseVersions: false`.
|
|
641
|
+
- **An app with last-write-wins.** It gives no expected version, so nothing changes. Its own storage must refuse a write with an expected version until it tests one. Add the guard to its `set`, `delete` and `setBatch`, and run the contract suite: its first case tests the refusal. To adopt the version later, stamp a version field on the server, give the storage a `versionOf` that tests it in the write, and give the same `versionOf` to the `HybridStorage` of the client. Then add `createWithVersions` to the contract run.
|
|
642
|
+
- **An app without versions.** No change: it gives no expected version. A storage of the app that implements `CollectionStorage` must refuse a write with an expected version, as above.
|
|
632
643
|
- **Other storages.** Each class that implements `CollectionStorage` reads the new options of `set`, `delete` and `setBatch`. It tests them in the write, or it rejects the write with `preconditionNotSupported()`. It never ignores them.
|
|
633
644
|
|
|
634
645
|
### Patch Changes
|
|
@@ -795,14 +806,14 @@
|
|
|
795
806
|
- The option `origin` of `HybridStorage` is the tag of the storage (a random `hybrid-…` tag by default). Each write of the storage to the local copy and to the remote has it. The write methods of `HybridStorage` and `ApiStorage` take `{ origin }`.
|
|
796
807
|
- `capture: "observe"`: the storage observes the local copy and queues each change with another origin. Thus an application can write to the local copy directly, for example with the synchronous writes of a SignalDB collection. In `write-through` and `remote-only` mode, the storage sends a captured change at once.
|
|
797
808
|
- The option `syncState` takes a `SyncStateStore`: `MemorySyncStateStore`, or `IndexedDbSyncStateStore` of `@procedures/store/indexeddb`. The store keeps the cursor and the base versions. A new storage with the same store and a durable local copy asks only for the changes since the cursor, and it finds the conflicts of the base versions. A failure of the store goes to the status (`operation: "store"`, `SyncStateError`), and the storage goes on.
|
|
798
|
-
- The option `feed` takes a `RemoteChangeFeed`. A delta whose `since` is the cursor applies without a read of the remote. A gap, a lost event, a new subscription or another delta makes one pull. A delta that comes during a pull applies after the pull, so the pull does not erase it
|
|
809
|
+
- The option `feed` takes a `RemoteChangeFeed`. A delta whose `since` is the cursor applies without a read of the remote. A gap, a lost event, a new subscription or another delta makes one pull. A delta that comes during a pull applies after the pull, so the pull does not erase it.
|
|
799
810
|
- In `write-through` mode, a pull or a delta does not write over an own write that waits for the remote, a set or a delete. The storage keeps the remote value of the id, and after the write it reads the id again: then the rules of a pull decide. A read of a missing id does not bring back an item whose own delete waits.
|
|
800
|
-
- With `versionOf`, the storage keeps the versions of its own writes until their echoes come (option `echoWindow`, 30 seconds by default). The echo of an older own write does not write over a newer local write
|
|
811
|
+
- With `versionOf`, the storage keeps the versions of its own writes until their echoes come (option `echoWindow`, 30 seconds by default). The echo of an older own write does not write over a newer local write.
|
|
801
812
|
- `EventsChangeFeed` of `@procedures/store` is the feed of the change events. Its source is a `Client`, a `WebSocketTransport` or another transport. It treats the events as hints: a gap of the numbers, a lost event, a hint and each confirmation of the subscription call `onGap()`.
|
|
802
813
|
- The core collection procedures publish `CollectionChangeEvent` `{ since, version, changed, deleted, origin }` on `ctx.bus`, under the topic `collections.<name>` (`collectionChangeTopic()`), while a subscriber listens. The changes come from `getChangesSince()` of the storage, and the events of one storage make a chain of versions. The option `changeEvents` of `createCollectionProcedures()` turns them off, or gives the topic of each call: the partition of CLI-17 goes there.
|
|
803
814
|
- A value reaches a subscriber only through the checks of a read. By default, an event has the ids and the versions only, and `EventsChangeFeed` gives it to `onHint()`: `HybridStorage` reads the values with `changes`, and a hint with only deletes applies without a read. With `changeEvents: { values: true }`, an event also has `values`: each row `{ id, value }` passes the output filter of the host (`admitItem`) for each subscriber, and a refused id goes in `withheld`, so the storage pulls it.
|
|
804
815
|
- `EventPublisher` refuses a topic whose reads the capability of the call does not permit (`FORBIDDEN`, `effects-exceeded`). Its new option `reads` gives the reads of a topic. The default, `collectionTopicReads()`, gives `collection:<name>` for `collections.<name>` and `collections.<name>.<partition>`. `ctx.admit` gives a procedure the output filter of its host for the data that it sends later.
|
|
805
|
-
- The syncs of one `HybridStorage` run one at a time: the deltas and the hints of the feed, the pulls, the pushes, the reads after an own write and the mode switches. A remote delta and a full sync never run at the same time
|
|
816
|
+
- The syncs of one `HybridStorage` run one at a time: the deltas and the hints of the feed, the pulls, the pushes, the reads after an own write and the mode switches. A remote delta and a full sync never run at the same time.
|
|
806
817
|
- The write inputs of the collection procedures take an optional `origin` (1 to 256 characters). The procedure gives it to the storage and to the event. A server before this change ignores the field.
|
|
807
818
|
- `Client.subscribe()` and `Client.events()` subscribe to the topics of the bus of the server through the middleware and the context of the client. A subscription has no deadline: the timeouts of the client do not apply to it, and only `metadata: { timeout }` in its options gives one.
|
|
808
819
|
- New exports: `collectionChangeTopic`, `CollectionChangeEvent` and `CollectionChangeEventsOptions` from `@procedures/client`, `./browser` and `./procedures`. `EventsChangeFeed`, `MemorySyncStateStore`, `SyncStateError` and the types `RemoteChangeFeed`, `RemoteChangeListener`, `RemoteChanges`, `EventSubscriber`, `ChangeEventSource`, `EventsChangeFeedOptions`, `SyncState`, `SyncStateChange` and `SyncStateStore` from `@procedures/store`. `IndexedDbSyncStateStore` and `MemorySyncStateStore` from `@procedures/store/indexeddb`.
|
package/README.md
CHANGED
|
@@ -393,7 +393,7 @@ const users = new HybridStorage(new ApiStorage(client, { collection: "users" }),
|
|
|
393
393
|
|
|
394
394
|
### The hook around a remote apply
|
|
395
395
|
|
|
396
|
-
The option `aroundRemoteApply` puts each apply of the remote changes inside a hook
|
|
396
|
+
The option `aroundRemoteApply` puts each apply of the remote changes inside a hook. For example, the hook starts a span of a trace with the `traceparent` of the server.
|
|
397
397
|
|
|
398
398
|
- The hook gets `hint`, `apply` and `context`. It starts `apply` one time and gives back its promise.
|
|
399
399
|
- `context.cause` is `"delta"`, `"hint"`, `"gap"` or `"pull"`. `context.hints` has the hints of the apply.
|