@procedures/store 0.18.0 → 0.19.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 +33 -0
- package/README.md +22 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/tab-coordinator.d.ts +131 -15
- package/dist/storage/tab-coordinator.d.ts.map +1 -1
- package/dist/storage/tab-coordinator.js +374 -32
- package/dist/storage/tab-coordinator.js.map +1 -1
- package/package.json +4 -4
- package/src/browser.ts +1 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/tab-coordinator.ts +455 -37
package/dist/browser.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export * from "./indexeddb.js";
|
|
|
21
21
|
export { HybridStorage, PendingWriteError, QueueFullError, MissingKeysError, QueueStoreError, ConflictError, ModeSwitchError, SyncStateError, } from "./storage/hybrid.js";
|
|
22
22
|
export type { HybridStorageOptions, HybridMode, LocalCopyStorage } from "./storage/hybrid.js";
|
|
23
23
|
export { TabCoordinator } from "./storage/tab-coordinator.js";
|
|
24
|
-
export type { TabAbortSignalLike, TabChannelFactory, TabChannelLike, TabCoordinatorOptions, TabLockManagerLike, TabRole, } from "./storage/tab-coordinator.js";
|
|
24
|
+
export type { TabAbortSignalLike, TabChannelFactory, TabChannelLike, TabCoordinatorOptions, TabLockManagerLike, TabRetryOptions, TabRole, } from "./storage/tab-coordinator.js";
|
|
25
25
|
export type { ConflictResolution, SyncError, SyncStatus } from "./storage/types.js";
|
|
26
26
|
export { ApiStorage } from "./storage/api.js";
|
|
27
27
|
export type { ApiStorageOptions } from "./storage/api.js";
|
package/dist/browser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,OAAO,GACR,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACd,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,OAAO,GACR,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACd,MAAM,mBAAmB,CAAC"}
|
package/dist/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAW9D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/storage/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export type { ApiStorageOptions } from "./api.js";
|
|
|
12
12
|
export { HybridStorage, PendingWriteError, QueueFullError, MissingKeysError, QueueStoreError, ConflictError, ModeSwitchError, SyncStateError, } from "./hybrid.js";
|
|
13
13
|
export type { HybridStorageOptions, HybridMode, LocalCopyStorage } from "./hybrid.js";
|
|
14
14
|
export { TabCoordinator } from "./tab-coordinator.js";
|
|
15
|
-
export type { TabAbortSignalLike, TabChannelFactory, TabChannelLike, TabCoordinatorOptions, TabLockManagerLike, TabRole, } from "./tab-coordinator.js";
|
|
15
|
+
export type { TabAbortSignalLike, TabChannelFactory, TabChannelLike, TabCoordinatorOptions, TabLockManagerLike, TabRetryOptions, TabRole, } from "./tab-coordinator.js";
|
|
16
16
|
export { EventsChangeFeed } from "./feed.js";
|
|
17
17
|
export type { ChangeEventSource, EventSubscriber, EventsChangeFeedOptions, RemoteChangeFeed, RemoteChangeHint, RemoteChangeListener, RemoteChanges, } from "./feed.js";
|
|
18
18
|
export { MemorySyncStateStore } from "./sync-state.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,UAAU,EACV,SAAS,EACT,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG/E,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,OAAO,GACR,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACd,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIlF,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAGnE,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAClF,YAAY,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAGtE,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,UAAU,EACV,SAAS,EACT,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG/E,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,OAAO,GACR,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACd,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIlF,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAGnE,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAClF,YAAY,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAGtE,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkBH,gBAAgB;AAChB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAG5B,wFAAwF;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,qFAAqF;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkBH,gBAAgB;AAChB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAG5B,wFAAwF;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,qFAAqF;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAUtD,+DAA+D;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAU7C,sFAAsF;AACtF,+DAA+D;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,+EAA+E;AAC/E,6EAA6E;AAC7E,mFAAmF;AACnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG9C,UAAU;AACV,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAGvD,kBAAkB;AAClB,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGlF,UAAU;AACV,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AAGtB,0EAA0E;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
* acknowledged.
|
|
19
19
|
* - Without the Web Locks API or `BroadcastChannel`, the coordinator is in the single mode: the tab
|
|
20
20
|
* is the leader at once, and it opens no channel.
|
|
21
|
+
* - A tab becomes the leader only after its `HybridStorage` loaded the queue. When the setup fails
|
|
22
|
+
* (the function `remote` throws, or the load of the queue fails), the tab reports the error and
|
|
23
|
+
* releases the lock. It stays a follower, and it asks for the lock again after a backoff (roadmap
|
|
24
|
+
* CLI-67). Thus a failure that goes away does not leave the browser without a sync.
|
|
25
|
+
* - The leader sends the status of its sync to the followers: at each change, and in answer to a
|
|
26
|
+
* hello. `getStatus()` and `onStatus()` give the status in each tab (roadmap CLI-65).
|
|
21
27
|
*
|
|
22
28
|
* The limits:
|
|
23
29
|
* - When the leader stops during a push, the next leader sends the operation again: the delivery to
|
|
@@ -32,7 +38,9 @@
|
|
|
32
38
|
*/
|
|
33
39
|
import type { CollectionStorage, StorageObserver } from "@procedures/collections";
|
|
34
40
|
import { type ListenerErrorHandler } from "@procedures/collections";
|
|
41
|
+
import { type Clock, type Duration } from "@procedures/client/browser";
|
|
35
42
|
import { HybridStorage, type HybridStorageOptions, type LocalCopyStorage } from "./hybrid.js";
|
|
43
|
+
import type { SyncStatus } from "./types.js";
|
|
36
44
|
/** The signal that stops a lock request that waits. The `AbortSignal` of a browser fits it. */
|
|
37
45
|
export interface TabAbortSignalLike {
|
|
38
46
|
readonly aborted: boolean;
|
|
@@ -63,7 +71,7 @@ export type TabChannelFactory = (name: string) => TabChannelLike;
|
|
|
63
71
|
* The role of a tab.
|
|
64
72
|
*
|
|
65
73
|
* - `follower`: the tab waits for the lock. It copies the changes of the other tabs, and it sends
|
|
66
|
-
* its own changes to the leader.
|
|
74
|
+
* its own changes to the leader. A tab whose setup failed is a follower until its next try.
|
|
67
75
|
* - `leader`: the tab holds the lock, and its `HybridStorage` runs the sync.
|
|
68
76
|
* - `single`: the browser has no Web Locks API or no `BroadcastChannel`. The tab runs the sync
|
|
69
77
|
* alone, and it opens no channel.
|
|
@@ -88,7 +96,10 @@ export interface TabCoordinatorOptions<T> {
|
|
|
88
96
|
* `InMemoryStorage`. A tab writes the batches of the other tabs to its copy.
|
|
89
97
|
*/
|
|
90
98
|
copy: "shared" | "tab";
|
|
91
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* The function that makes the remote of the `HybridStorage`. Only a tab that got the lock calls
|
|
101
|
+
* it. When it throws, the tab releases the lock and tries again after the backoff of `retry`.
|
|
102
|
+
*/
|
|
92
103
|
remote: () => CollectionStorage<T>;
|
|
93
104
|
/**
|
|
94
105
|
* The options of the `HybridStorage` of the leader. The coordinator sets `local` and
|
|
@@ -106,12 +117,45 @@ export interface TabCoordinatorOptions<T> {
|
|
|
106
117
|
* @default a function that opens a `BroadcastChannel`, when the browser has it
|
|
107
118
|
*/
|
|
108
119
|
channel?: TabChannelFactory | null;
|
|
120
|
+
/**
|
|
121
|
+
* The wait before a new try after a failed setup of the sync (roadmap CLI-67). A setup fails when
|
|
122
|
+
* the function `remote` throws, when the `HybridStorage` cannot start, or when it cannot load its
|
|
123
|
+
* queue. The tab releases the lock, stays a follower, and asks for the lock again after the wait.
|
|
124
|
+
* In the single mode, the tab tries the setup again after the wait.
|
|
125
|
+
*
|
|
126
|
+
* After `n` failed setups in a row, the wait is `delay × factor^(n − 1)`, at most `maxDelay`. The
|
|
127
|
+
* random part `jitter` makes the wait shorter by up to this fraction. A setup that succeeds sets
|
|
128
|
+
* the wait back to `delay`.
|
|
129
|
+
*/
|
|
130
|
+
retry?: TabRetryOptions;
|
|
131
|
+
/**
|
|
132
|
+
* The clock of the wait of `retry`. A test gives `fakeClock` of `@mark1russell7/service/testing`.
|
|
133
|
+
* @default the `clock` of `hybrid`, or else the clock of the platform (`realClock` of `@procedures/client`)
|
|
134
|
+
*/
|
|
135
|
+
clock?: Clock;
|
|
136
|
+
/**
|
|
137
|
+
* The random numbers of the jitter of `retry`, from 0 up to 1. A test gives a fixed generator.
|
|
138
|
+
* @default the `random` of `hybrid`, or else `Math.random`
|
|
139
|
+
*/
|
|
140
|
+
random?: () => number;
|
|
109
141
|
/**
|
|
110
142
|
* The function that gets the errors: of the lock, of the channel, of a write to the local copy,
|
|
111
|
-
* of the `HybridStorage
|
|
143
|
+
* of the `HybridStorage`, of a failed setup and of the observers. The default throws the error
|
|
144
|
+
* again in a microtask.
|
|
112
145
|
*/
|
|
113
146
|
onError?: ListenerErrorHandler;
|
|
114
147
|
}
|
|
148
|
+
/** The backoff of a new try after a failed setup of the sync (roadmap CLI-67). */
|
|
149
|
+
export interface TabRetryOptions {
|
|
150
|
+
/** The wait after the first failure, for example `seconds(1)`. It must be more than zero. @default 1 second */
|
|
151
|
+
delay?: Duration;
|
|
152
|
+
/** The number that multiplies the wait after each failure, 1 or more. @default 2 */
|
|
153
|
+
factor?: number;
|
|
154
|
+
/** The longest wait, for example `minutes(1)`. A `delay` that is longer is the longest wait. @default 1 minute */
|
|
155
|
+
maxDelay?: Duration;
|
|
156
|
+
/** The random part of each wait, from 0 to 1. The wait is from `(1 − jitter) ×` the backoff up to the backoff. @default 0.5 */
|
|
157
|
+
jitter?: number;
|
|
158
|
+
}
|
|
115
159
|
/**
|
|
116
160
|
* One leader tab runs the sync of a `HybridStorage`, and the other tabs copy its changes.
|
|
117
161
|
*
|
|
@@ -133,6 +177,7 @@ export interface TabCoordinatorOptions<T> {
|
|
|
133
177
|
* });
|
|
134
178
|
*
|
|
135
179
|
* users.observe((batch) => render(batch)); // The changes of this tab and of the other tabs
|
|
180
|
+
* users.onStatus((status) => showSync(status)); // The status of the sync of the leader, in each tab
|
|
136
181
|
* await local.set("1", { name: "Ada" }); // The leader pushes the write
|
|
137
182
|
* ```
|
|
138
183
|
*/
|
|
@@ -151,11 +196,31 @@ export declare class TabCoordinator<T> {
|
|
|
151
196
|
private readonly onError;
|
|
152
197
|
private readonly observers;
|
|
153
198
|
private readonly roleListeners;
|
|
199
|
+
private readonly statusListeners;
|
|
154
200
|
/** The observers that the `HybridStorage` of the leader adds to its local copy: the capture */
|
|
155
201
|
private readonly captures;
|
|
202
|
+
/** The backoff of a new try after a failed setup, its clock and its random numbers */
|
|
203
|
+
private readonly backoff;
|
|
204
|
+
private readonly clock;
|
|
205
|
+
private readonly random;
|
|
156
206
|
private currentRole;
|
|
207
|
+
/** The lock manager, or undefined in the single mode */
|
|
208
|
+
private locks;
|
|
157
209
|
private channel;
|
|
158
210
|
private hybrid;
|
|
211
|
+
/** The storage of this tab while it loads its queue, before the tab leads */
|
|
212
|
+
private candidate;
|
|
213
|
+
/** The number of the failed setups in a row */
|
|
214
|
+
private failures;
|
|
215
|
+
/** The stop of the wait before the next try */
|
|
216
|
+
private cancelRetry;
|
|
217
|
+
/** The status of the sync: of the `HybridStorage` of this tab, or of the leader */
|
|
218
|
+
private status;
|
|
219
|
+
/** In the leader: the number of its last status. In a follower: the tab and the number of the last status that it got. */
|
|
220
|
+
private statusSeq;
|
|
221
|
+
private statusFrom;
|
|
222
|
+
/** The stop of the status of the `HybridStorage` of this tab */
|
|
223
|
+
private stopStatus;
|
|
159
224
|
/** The stop of the observer of the changes of this tab: on the local copy, or on the `HybridStorage` of the leader */
|
|
160
225
|
private stopTap;
|
|
161
226
|
/** True while the leader gives a batch of another tab to the capture of its `HybridStorage` */
|
|
@@ -182,9 +247,9 @@ export declare class TabCoordinator<T> {
|
|
|
182
247
|
/** True when this tab runs the sync: the leader, or a tab in the single mode. */
|
|
183
248
|
get isLeader(): boolean;
|
|
184
249
|
/**
|
|
185
|
-
* The `HybridStorage` of the sync while this tab runs it, or else undefined.
|
|
186
|
-
* gives the state of the sync. Write to the local copy, not to this
|
|
187
|
-
* in the same way.
|
|
250
|
+
* The `HybridStorage` of the sync while this tab runs it, or else undefined. `getStatus()` of the
|
|
251
|
+
* coordinator gives the state of the sync in each tab. Write to the local copy, not to this
|
|
252
|
+
* storage: each tab then writes in the same way.
|
|
188
253
|
*/
|
|
189
254
|
get syncStorage(): HybridStorage<T> | undefined;
|
|
190
255
|
/**
|
|
@@ -204,10 +269,33 @@ export declare class TabCoordinator<T> {
|
|
|
204
269
|
* @throws Error after `close()`
|
|
205
270
|
*/
|
|
206
271
|
onRole(listener: (role: TabRole) => void): () => void;
|
|
272
|
+
/**
|
|
273
|
+
* The status of the sync (roadmap CLI-65), or undefined before the first status and after
|
|
274
|
+
* `close()`.
|
|
275
|
+
*
|
|
276
|
+
* - In the leader and in the single mode, it is the status of the `HybridStorage` of this tab.
|
|
277
|
+
* - In a follower, it is the last status that the leader sent. A new tab gets it in the answer to
|
|
278
|
+
* its hello. After a change of the leader, a follower keeps the last status until the new
|
|
279
|
+
* leader sends its status.
|
|
280
|
+
* - In a follower, `error.error` is a copy of the error of the leader: an `Error` with its `name`,
|
|
281
|
+
* its `message` and its `code`. The copy has no `cause`.
|
|
282
|
+
*/
|
|
283
|
+
getStatus(): SyncStatus | undefined;
|
|
284
|
+
/**
|
|
285
|
+
* This method starts to send the status of the sync to a listener at each change (roadmap
|
|
286
|
+
* CLI-65): in the leader, each status of its `HybridStorage`, and in a follower, each status that
|
|
287
|
+
* the leader sends. The listener gets each status one time. When the tab becomes the leader, the
|
|
288
|
+
* listener gets the status of its own `HybridStorage`.
|
|
289
|
+
*
|
|
290
|
+
* @returns The function that stops the statuses. A second use of it does nothing.
|
|
291
|
+
* @throws Error after `close()`
|
|
292
|
+
*/
|
|
293
|
+
onStatus(listener: (status: SyncStatus) => void): () => void;
|
|
207
294
|
/**
|
|
208
295
|
* This method closes the coordinator.
|
|
209
296
|
*
|
|
210
|
-
* - A follower stops its lock request. It does not become the leader.
|
|
297
|
+
* - A follower stops its lock request, or its wait before a new try. It does not become the leader.
|
|
298
|
+
* - A tab that loads its queue to become the leader closes its `HybridStorage`, and releases the lock.
|
|
211
299
|
* - The leader closes its `HybridStorage`: it sends the queue, and the queue store keeps the
|
|
212
300
|
* operations that the remote did not take. Then the leader releases the lock, and the next
|
|
213
301
|
* tab becomes the leader.
|
|
@@ -220,16 +308,34 @@ export declare class TabCoordinator<T> {
|
|
|
220
308
|
/** This method asks for the lock. The tab becomes the leader when it gets the lock. */
|
|
221
309
|
private elect;
|
|
222
310
|
/**
|
|
223
|
-
* This method makes the `HybridStorage` of
|
|
224
|
-
*
|
|
311
|
+
* This method makes the `HybridStorage` of a tab that got the lock, and waits for the load of its
|
|
312
|
+
* queue. Then the tab becomes the leader. Until then, the tab is a follower: its own batches go to
|
|
313
|
+
* the other tabs and to its outbox, and the capture of the storage ignores the local copy.
|
|
314
|
+
*
|
|
315
|
+
* @returns False when the setup failed (the error went to `onError`), or after `close()`
|
|
316
|
+
*/
|
|
317
|
+
private takeLead;
|
|
318
|
+
/** This method makes the `HybridStorage` of the single mode. The tab tries again after the backoff when it fails. */
|
|
319
|
+
private startSingle;
|
|
320
|
+
/**
|
|
321
|
+
* This method makes the `HybridStorage` of the sync, with its observer. Its capture ignores the
|
|
322
|
+
* local copy until the tab leads.
|
|
225
323
|
*
|
|
226
|
-
* @returns
|
|
324
|
+
* @returns Undefined when the remote or the storage could not start (the error went to `onError`), or after `close()`
|
|
325
|
+
*/
|
|
326
|
+
private makeCandidate;
|
|
327
|
+
/**
|
|
328
|
+
* This method makes this tab the leader, or the single tab, with the storage of a candidate. The
|
|
329
|
+
* capture of the storage gets the batches of this tab that no leader acknowledged.
|
|
227
330
|
*/
|
|
228
|
-
private
|
|
331
|
+
private promote;
|
|
332
|
+
/** This method asks for the lock again, or tries the single mode again, after the backoff (roadmap CLI-67). */
|
|
333
|
+
private retryLater;
|
|
229
334
|
/**
|
|
230
335
|
* The local copy for the `HybridStorage` of the leader. Its `observe()` gives the changes of the
|
|
231
|
-
* local copy and the batches of the other tabs, so the capture queues both.
|
|
232
|
-
* nothing: the application owns
|
|
336
|
+
* local copy and the batches of the other tabs, so the capture queues both. It gives the changes
|
|
337
|
+
* of the local copy only when `gate` is open. Its `close()` does nothing: the application owns
|
|
338
|
+
* the local copy.
|
|
233
339
|
*/
|
|
234
340
|
private captureCopy;
|
|
235
341
|
/**
|
|
@@ -239,6 +345,12 @@ export declare class TabCoordinator<T> {
|
|
|
239
345
|
*/
|
|
240
346
|
private capture;
|
|
241
347
|
private setRole;
|
|
348
|
+
/** A status of the `HybridStorage` of this tab. The leader sends each new status to the followers. */
|
|
349
|
+
private onOwnStatus;
|
|
350
|
+
/** This method sends the last status of the leader, with its number. */
|
|
351
|
+
private postStatus;
|
|
352
|
+
/** A status of the leader. A tab that runs the sync keeps its own status. */
|
|
353
|
+
private onLeaderStatus;
|
|
242
354
|
/**
|
|
243
355
|
* A batch of the local copy of a follower. The writes of the coordinator itself (the batches of
|
|
244
356
|
* the other tabs in a copy of each tab) have the tag of the coordinator, and do not go out again.
|
|
@@ -249,7 +361,10 @@ export declare class TabCoordinator<T> {
|
|
|
249
361
|
* a write to the storage, or a change of the sync.
|
|
250
362
|
*/
|
|
251
363
|
private onLeaderBatch;
|
|
252
|
-
/**
|
|
364
|
+
/**
|
|
365
|
+
* This method gives a batch of this tab to its observers and to the other tabs. A follower keeps
|
|
366
|
+
* it for the leader. A single tab whose setup failed keeps it for its next try.
|
|
367
|
+
*/
|
|
253
368
|
private share;
|
|
254
369
|
/** This method tells the leader the batches of this tab that no leader acknowledged. */
|
|
255
370
|
private hello;
|
|
@@ -264,7 +379,8 @@ export declare class TabCoordinator<T> {
|
|
|
264
379
|
private onChanges;
|
|
265
380
|
/**
|
|
266
381
|
* The hello of another tab. The leader captures the batches that it did not capture, and then each
|
|
267
|
-
* batch of the tab after `seq`. Each tab copies the batches that it
|
|
382
|
+
* batch of the tab after `seq`. It answers with its status. Each tab copies the batches that it
|
|
383
|
+
* did not see.
|
|
268
384
|
*/
|
|
269
385
|
private onHello;
|
|
270
386
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tab-coordinator.d.ts","sourceRoot":"","sources":["../../src/storage/tab-coordinator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tab-coordinator.d.ts","sourceRoot":"","sources":["../../src/storage/tab-coordinator.ts"],"names":[],"mappings":"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"}
|