syzygy-services-rn 1.1.0 → 1.2.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/.eslintrc.json +47 -0
- package/.github/workflows/release.yml +12 -5
- package/.prettierrc +9 -0
- package/CHANGELOG.md +13 -1
- package/CONTRACT_TESTS.md +10 -0
- package/README.md +2 -2
- package/dist/__tests__/deviceservices/DeviceProvider.test.js +6 -0
- package/dist/__tests__/deviceservices/DeviceProvider.test.js.map +1 -1
- package/dist/__tests__/networking/RetryIntegration.test.js +102 -24
- package/dist/__tests__/networking/RetryIntegration.test.js.map +1 -1
- package/dist/__tests__/persistence/StorageProvider.test.js +9 -0
- package/dist/__tests__/persistence/StorageProvider.test.js.map +1 -1
- package/dist/deviceservices/DeviceProvider.d.ts +1 -0
- package/dist/deviceservices/DeviceProvider.d.ts.map +1 -1
- package/dist/deviceservices/DeviceProvider.js +9 -1
- package/dist/deviceservices/DeviceProvider.js.map +1 -1
- package/dist/networking/NetworkClient.d.ts +13 -2
- package/dist/networking/NetworkClient.d.ts.map +1 -1
- package/dist/networking/NetworkClient.js +18 -4
- package/dist/networking/NetworkClient.js.map +1 -1
- package/dist/persistence/StorageProvider.d.ts +4 -0
- package/dist/persistence/StorageProvider.d.ts.map +1 -1
- package/dist/persistence/StorageProvider.js +4 -0
- package/dist/persistence/StorageProvider.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/deviceservices/DeviceProvider.test.ts +7 -0
- package/src/__tests__/networking/RetryIntegration.test.ts +121 -25
- package/src/__tests__/persistence/StorageProvider.test.ts +10 -0
- package/src/deviceservices/DeviceProvider.ts +9 -1
- package/src/networking/NetworkClient.ts +27 -5
- package/src/persistence/StorageProvider.ts +4 -0
- package/syzygy.yml +2 -2
package/.eslintrc.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"root": true,
|
|
3
|
+
"parser": "@typescript-eslint/parser",
|
|
4
|
+
"parserOptions": {
|
|
5
|
+
"ecmaVersion": 2020,
|
|
6
|
+
"sourceType": "module",
|
|
7
|
+
"ecmaFeatures": { "jsx": true }
|
|
8
|
+
},
|
|
9
|
+
"plugins": ["@typescript-eslint", "react", "react-hooks", "react-native", "import"],
|
|
10
|
+
"extends": [
|
|
11
|
+
"eslint:recommended",
|
|
12
|
+
"plugin:@typescript-eslint/recommended",
|
|
13
|
+
"plugin:react/recommended",
|
|
14
|
+
"plugin:react-hooks/recommended",
|
|
15
|
+
// Must always be last: disables ESLint formatting rules that would
|
|
16
|
+
// otherwise conflict with Prettier's output.
|
|
17
|
+
"eslint-config-prettier"
|
|
18
|
+
],
|
|
19
|
+
"env": {
|
|
20
|
+
"es6": true,
|
|
21
|
+
"node": true,
|
|
22
|
+
"react-native/react-native": true
|
|
23
|
+
},
|
|
24
|
+
"settings": {
|
|
25
|
+
"react": { "version": "detect" }
|
|
26
|
+
},
|
|
27
|
+
"rules": {
|
|
28
|
+
"@typescript-eslint/no-unused-vars": [
|
|
29
|
+
"warn",
|
|
30
|
+
{ "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }
|
|
31
|
+
],
|
|
32
|
+
"@typescript-eslint/no-explicit-any": "warn",
|
|
33
|
+
"react/prop-types": "off",
|
|
34
|
+
"react/react-in-jsx-scope": "off",
|
|
35
|
+
"react-native/no-inline-styles": "warn",
|
|
36
|
+
"react-native/no-unused-styles": "warn",
|
|
37
|
+
"import/order": [
|
|
38
|
+
"warn",
|
|
39
|
+
{
|
|
40
|
+
"groups": ["builtin", "external", "internal", "parent", "sibling", "index"],
|
|
41
|
+
"alphabetize": { "order": "asc", "caseInsensitive": true },
|
|
42
|
+
"newlines-between": "always"
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"ignorePatterns": ["dist", "node_modules", "lib", "build"]
|
|
47
|
+
}
|
|
@@ -21,10 +21,17 @@ jobs:
|
|
|
21
21
|
contents: read
|
|
22
22
|
steps:
|
|
23
23
|
- uses: actions/checkout@v4
|
|
24
|
-
-
|
|
24
|
+
- name: Set up Node
|
|
25
|
+
uses: actions/setup-node@v4
|
|
25
26
|
with:
|
|
26
27
|
node-version: '24'
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: npm ci
|
|
30
|
+
- name: Lint
|
|
31
|
+
run: npm run lint
|
|
32
|
+
- name: Type check
|
|
33
|
+
run: npm run typecheck
|
|
34
|
+
- name: Test
|
|
35
|
+
run: npm test
|
|
36
|
+
- name: Publish to npm
|
|
37
|
+
run: npm publish --access=public --provenance
|
package/.prettierrc
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.2.0] - 2026-09-19
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- `DeviceProvider`: concurrent `getDeviceId()` calls now share one UUID generation via single-flight Promise memoization
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- npm publish gated behind lint + typecheck + test in release.yml
|
|
17
|
+
- `StorageProvider.set(value, key)` argument order documented — Foundation v1.2.0 TODO noted
|
|
18
|
+
- Canonical backoff policy: 500ms base, 2.0× multiplier, full jitter, 8 000ms cap, max 3 retries
|
|
19
|
+
- Foundation dependency updated to ^1.2.0
|
|
20
|
+
|
|
10
21
|
## [1.1.0] - 2026-09-13
|
|
11
22
|
|
|
12
23
|
### Added
|
|
@@ -57,6 +68,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
57
68
|
- CrashReporter interface and console crash logging stub
|
|
58
69
|
- WebSocketProvider interface and native WebSocket implementation stub
|
|
59
70
|
|
|
60
|
-
[Unreleased]: https://github.com/Syzygy-Hub/syzygy-services-rn/compare/1.
|
|
71
|
+
[Unreleased]: https://github.com/Syzygy-Hub/syzygy-services-rn/compare/1.2.0...HEAD
|
|
72
|
+
[1.2.0]: https://github.com/Syzygy-Hub/syzygy-services-rn/compare/1.1.0...1.2.0
|
|
61
73
|
[1.1.0]: https://github.com/Syzygy-Hub/syzygy-services-rn/compare/1.0.0...1.1.0
|
|
62
74
|
[1.0.0]: https://github.com/Syzygy-Hub/syzygy-services-rn/releases/tag/1.0.0
|
package/CONTRACT_TESTS.md
CHANGED
|
@@ -106,3 +106,13 @@ implemented in this repo's test suite; tests marked 🔲 are not yet implemented
|
|
|
106
106
|
| simulateBinaryMessage() emits to binary callback | ✅ |
|
|
107
107
|
| dispose() closes connection | ✅ |
|
|
108
108
|
| dispose() is idempotent | ✅ |
|
|
109
|
+
|
|
110
|
+
## Idempotency Tests
|
|
111
|
+
|
|
112
|
+
| Module | Scenario | Status |
|
|
113
|
+
|--------|----------|--------|
|
|
114
|
+
| networking | `dispose()` called twice does not throw | ❌ (test not yet implemented) |
|
|
115
|
+
| websocket | `disconnect()` called before `connect()` does not throw | ❌ (test not yet implemented) |
|
|
116
|
+
| websocket | `disconnect()` called twice does not throw | ❌ (test not yet implemented) |
|
|
117
|
+
| auth | `signOut()` called when already signed out does not throw | ❌ (test not yet implemented) |
|
|
118
|
+
| persistence | `clear()` called on empty store does not throw | ❌ (test not yet implemented) |
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](https://reactnative.dev) [](https://www.typescriptlang.org) [](https://github.com/Syzygy-Hub/syzygy-services-rn/actions/workflows/ci.yml) [](https://reactnative.dev) [](https://www.typescriptlang.org) [](https://github.com/Syzygy-Hub/syzygy-services-rn/actions/workflows/ci.yml) [](https://github.com/Syzygy-Hub/syzygy-services-rn/releases) [](LICENSE)
|
|
2
2
|
|
|
3
3
|
<picture>
|
|
4
4
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/Syzygy-Hub/.github/main/brand/assets/banners/syzygy-banner-dark-1200.png">
|
|
@@ -38,7 +38,7 @@ npm install syzygy-services-rn
|
|
|
38
38
|
|
|
39
39
|
## Dependencies
|
|
40
40
|
|
|
41
|
-
- `syzygy-foundation-rn` ^1.
|
|
41
|
+
- `syzygy-foundation-rn` ^1.2.0
|
|
42
42
|
|
|
43
43
|
## Ecosystem
|
|
44
44
|
|
|
@@ -62,5 +62,11 @@ describe('NodeDeviceProvider', () => {
|
|
|
62
62
|
const [id1, id2] = await Promise.all([p1.deviceId, p2.deviceId]);
|
|
63
63
|
expect(id1).not.toBe(id2);
|
|
64
64
|
});
|
|
65
|
+
it('concurrent getDeviceId calls all return same UUID', async () => {
|
|
66
|
+
const storage = new StorageProvider_1.InMemoryStorageProvider();
|
|
67
|
+
const provider = new DeviceProvider_1.NodeDeviceProvider({ storage });
|
|
68
|
+
const results = await Promise.all(Array.from({ length: 10 }, () => provider.deviceId));
|
|
69
|
+
expect(new Set(results).size).toBe(1);
|
|
70
|
+
});
|
|
65
71
|
});
|
|
66
72
|
//# sourceMappingURL=DeviceProvider.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceProvider.test.js","sourceRoot":"","sources":["../../../src/__tests__/deviceservices/DeviceProvider.test.ts"],"names":[],"mappings":";;AAAA,wEAAyE;AACzE,uEAA4E;AAE5E,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,OAAO,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,OAAO,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,OAAO,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1E,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,OAAO,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,OAAO,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,OAAO,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACxE,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,OAAO,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACrD,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC;QACnC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,OAAO,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC;QACpC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,OAAO,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC9C,MAAM,SAAS,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC;QAErC,MAAM,SAAS,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC;QAErC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,EAAE,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,IAAI,yCAAuB,EAAE,EAAE,CAAC,CAAC;QAC9E,MAAM,EAAE,GAAG,IAAI,mCAAkB,CAAC,EAAE,OAAO,EAAE,IAAI,yCAAuB,EAAE,EAAE,CAAC,CAAC;QAC9E,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"DeviceProvider.test.js","sourceRoot":"","sources":["../../../src/__tests__/deviceservices/DeviceProvider.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -100,27 +100,27 @@ describe('FetchNetworkClient — retry integration', () => {
|
|
|
100
100
|
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
101
101
|
expect(mockFetch).toHaveBeenCalledTimes(maxRetries + 1);
|
|
102
102
|
});
|
|
103
|
-
it('exponential backoff: delay
|
|
103
|
+
it('exponential backoff: delay grows with each retry (jitter range check)', async () => {
|
|
104
104
|
const baseDelay = 100;
|
|
105
|
+
const capMs = 8000;
|
|
105
106
|
const maxRetries = 3;
|
|
106
107
|
const mockFetch = makeAlwaysFail(500);
|
|
107
108
|
global.fetch = mockFetch;
|
|
108
|
-
//
|
|
109
|
-
// attempt 1 →
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
baseDelay * Math.pow(2,
|
|
109
|
+
// Canonical policy: delay = random(0, min(cap, base * 2^attempt))
|
|
110
|
+
// attempt 1 → [0, min(cap, base*2^0)] = [0, 100]
|
|
111
|
+
// attempt 2 → [0, min(cap, base*2^1)] = [0, 200]
|
|
112
|
+
// attempt 3 → [0, min(cap, base*2^2)] = [0, 400]
|
|
113
|
+
const expectedCaps = [
|
|
114
|
+
Math.min(capMs, baseDelay * Math.pow(2, 0)),
|
|
115
|
+
Math.min(capMs, baseDelay * Math.pow(2, 1)),
|
|
116
|
+
Math.min(capMs, baseDelay * Math.pow(2, 2)),
|
|
114
117
|
];
|
|
115
|
-
// Verify via the observable: stub setTimeout so retries run instantly,
|
|
116
|
-
// capture only delays in the [baseDelay..] range (exclude the per-request
|
|
117
|
-
// abort timeout which is set to timeoutSeconds * 1000 = 30000 ms).
|
|
118
118
|
const capturedDelays = [];
|
|
119
119
|
jest
|
|
120
120
|
.spyOn(global, 'setTimeout')
|
|
121
121
|
.mockImplementation((fn, ms, ...args) => {
|
|
122
122
|
const delay = ms ?? 0;
|
|
123
|
-
if (delay
|
|
123
|
+
if (delay >= 0 && delay <= baseDelay * 10) {
|
|
124
124
|
// Only capture retry-range delays
|
|
125
125
|
capturedDelays.push(delay);
|
|
126
126
|
}
|
|
@@ -128,9 +128,17 @@ describe('FetchNetworkClient — retry integration', () => {
|
|
|
128
128
|
fn(...args);
|
|
129
129
|
return 0;
|
|
130
130
|
});
|
|
131
|
-
const client = new NetworkClient_1.FetchNetworkClient({
|
|
131
|
+
const client = new NetworkClient_1.FetchNetworkClient({
|
|
132
|
+
maxRetries,
|
|
133
|
+
retryBaseDelayMs: baseDelay,
|
|
134
|
+
retryCapMs: capMs,
|
|
135
|
+
});
|
|
132
136
|
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
133
|
-
expect(capturedDelays).
|
|
137
|
+
expect(capturedDelays).toHaveLength(maxRetries);
|
|
138
|
+
capturedDelays.forEach((delay, i) => {
|
|
139
|
+
expect(delay).toBeGreaterThanOrEqual(0);
|
|
140
|
+
expect(delay).toBeLessThanOrEqual(expectedCaps[i]);
|
|
141
|
+
});
|
|
134
142
|
});
|
|
135
143
|
it('zero maxRetries means no retry — only one attempt', async () => {
|
|
136
144
|
installDelayStub();
|
|
@@ -161,25 +169,32 @@ describe('FetchNetworkClient — injectable BackoffClock (deterministic backoff)
|
|
|
161
169
|
afterEach(() => {
|
|
162
170
|
jest.restoreAllMocks();
|
|
163
171
|
});
|
|
164
|
-
it('injectable BackoffClock is called once per retry with
|
|
172
|
+
it('injectable BackoffClock is called once per retry with jitter delays in expected range', async () => {
|
|
165
173
|
const { backoffClock, delays } = makeInjectableSleep();
|
|
166
174
|
const baseDelay = 100;
|
|
175
|
+
const capMs = 8000;
|
|
167
176
|
const maxRetries = 3;
|
|
168
177
|
const mockFetch = makeAlwaysFail(500);
|
|
169
178
|
global.fetch = mockFetch;
|
|
170
179
|
const client = new NetworkClient_1.FetchNetworkClient({
|
|
171
180
|
maxRetries,
|
|
172
181
|
retryBaseDelayMs: baseDelay,
|
|
182
|
+
retryCapMs: capMs,
|
|
173
183
|
backoffClock,
|
|
174
184
|
});
|
|
175
185
|
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
176
186
|
// backoffClock called once per retry (not for the initial attempt)
|
|
177
187
|
expect(delays).toHaveLength(maxRetries);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
baseDelay * Math.pow(2,
|
|
181
|
-
baseDelay * Math.pow(2,
|
|
182
|
-
|
|
188
|
+
// Canonical policy: delay = random(0, min(cap, base * 2^attempt))
|
|
189
|
+
const expectedCaps = [
|
|
190
|
+
Math.min(capMs, baseDelay * Math.pow(2, 0)), // [0, 100]
|
|
191
|
+
Math.min(capMs, baseDelay * Math.pow(2, 1)), // [0, 200]
|
|
192
|
+
Math.min(capMs, baseDelay * Math.pow(2, 2)), // [0, 400]
|
|
193
|
+
];
|
|
194
|
+
delays.forEach((delay, i) => {
|
|
195
|
+
expect(delay).toBeGreaterThanOrEqual(0);
|
|
196
|
+
expect(delay).toBeLessThanOrEqual(expectedCaps[i]);
|
|
197
|
+
});
|
|
183
198
|
});
|
|
184
199
|
it('injectable BackoffClock is NOT called on first attempt (no prior failure)', async () => {
|
|
185
200
|
const { backoffClock, delays } = makeInjectableSleep();
|
|
@@ -202,28 +217,39 @@ describe('FetchNetworkClient — injectable BackoffClock (deterministic backoff)
|
|
|
202
217
|
it('injectable BackoffClock records partial delays when server recovers mid-retry', async () => {
|
|
203
218
|
const { backoffClock, delays } = makeInjectableSleep();
|
|
204
219
|
const baseDelay = 50;
|
|
220
|
+
const capMs = 8000;
|
|
205
221
|
global.fetch = makeRecoverAfter(2);
|
|
206
222
|
const client = new NetworkClient_1.FetchNetworkClient({
|
|
207
223
|
maxRetries: 3,
|
|
208
224
|
retryBaseDelayMs: baseDelay,
|
|
225
|
+
retryCapMs: capMs,
|
|
209
226
|
backoffClock,
|
|
210
227
|
});
|
|
211
228
|
const response = await client.execute(makeRequest());
|
|
212
229
|
expect(response.statusCode).toBe(200);
|
|
213
230
|
// 2 failures → 2 sleeps
|
|
214
231
|
expect(delays).toHaveLength(2);
|
|
215
|
-
|
|
232
|
+
// Canonical policy: delay = random(0, min(cap, base * 2^attempt))
|
|
233
|
+
const expectedCaps = [
|
|
234
|
+
Math.min(capMs, baseDelay * Math.pow(2, 0)), // [0, 50]
|
|
235
|
+
Math.min(capMs, baseDelay * Math.pow(2, 1)), // [0, 100]
|
|
236
|
+
];
|
|
237
|
+
delays.forEach((delay, i) => {
|
|
238
|
+
expect(delay).toBeGreaterThanOrEqual(0);
|
|
239
|
+
expect(delay).toBeLessThanOrEqual(expectedCaps[i]);
|
|
240
|
+
});
|
|
216
241
|
});
|
|
217
242
|
it('default BackoffClock (no injection) still works — setTimeout is used for retry delay', async () => {
|
|
218
243
|
// Stub setTimeout so the test runs fast; filter for retry-range delays only.
|
|
219
244
|
const baseDelay = 10;
|
|
245
|
+
const capMs = 8000;
|
|
220
246
|
const capturedDelays = [];
|
|
221
247
|
jest
|
|
222
248
|
.spyOn(global, 'setTimeout')
|
|
223
249
|
.mockImplementation((fn, ms, ...args) => {
|
|
224
250
|
const d = ms ?? 0;
|
|
225
251
|
// Capture only the retry-range delay (not the per-request abort timeout)
|
|
226
|
-
if (d
|
|
252
|
+
if (d >= 0 && d <= baseDelay * 10)
|
|
227
253
|
capturedDelays.push(d);
|
|
228
254
|
fn(...args);
|
|
229
255
|
return 0;
|
|
@@ -231,11 +257,63 @@ describe('FetchNetworkClient — injectable BackoffClock (deterministic backoff)
|
|
|
231
257
|
const mockFetch = makeAlwaysFail(500);
|
|
232
258
|
global.fetch = mockFetch;
|
|
233
259
|
// No backoffClock injected — uses default setTimeout-backed delay
|
|
234
|
-
const client = new NetworkClient_1.FetchNetworkClient({
|
|
260
|
+
const client = new NetworkClient_1.FetchNetworkClient({
|
|
261
|
+
maxRetries: 1,
|
|
262
|
+
retryBaseDelayMs: baseDelay,
|
|
263
|
+
retryCapMs: capMs,
|
|
264
|
+
});
|
|
235
265
|
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
236
|
-
// 1 retry → 1 delay recorded in the retry-range
|
|
266
|
+
// 1 retry → 1 delay recorded in the retry-range (jittered: [0, min(cap, base)])
|
|
237
267
|
expect(capturedDelays).toHaveLength(1);
|
|
238
|
-
expect(capturedDelays[0]).
|
|
268
|
+
expect(capturedDelays[0]).toBeGreaterThanOrEqual(0);
|
|
269
|
+
expect(capturedDelays[0]).toBeLessThanOrEqual(Math.min(capMs, baseDelay));
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
// ---------------------------------------------------------------------------
|
|
273
|
+
// Canonical backoff policy contract assertions
|
|
274
|
+
// Verifies the cross-platform backoff contract:
|
|
275
|
+
// delay = random(0, min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * BACKOFF_MULTIPLIER^attempt))
|
|
276
|
+
// ---------------------------------------------------------------------------
|
|
277
|
+
describe('Canonical backoff policy — range assertions', () => {
|
|
278
|
+
afterEach(() => {
|
|
279
|
+
jest.restoreAllMocks();
|
|
280
|
+
});
|
|
281
|
+
it('attempt 0 (retry 1): delay in [0, 500]', async () => {
|
|
282
|
+
const { backoffClock, delays } = makeInjectableSleep();
|
|
283
|
+
global.fetch = makeAlwaysFail(500);
|
|
284
|
+
const client = new NetworkClient_1.FetchNetworkClient({ maxRetries: 1, backoffClock });
|
|
285
|
+
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
286
|
+
expect(delays).toHaveLength(1);
|
|
287
|
+
expect(delays[0]).toBeGreaterThanOrEqual(0);
|
|
288
|
+
expect(delays[0]).toBeLessThanOrEqual(Math.min(NetworkClient_1.BACKOFF_CAP_MS, NetworkClient_1.BACKOFF_BASE_MS * Math.pow(NetworkClient_1.BACKOFF_MULTIPLIER, 0)));
|
|
289
|
+
});
|
|
290
|
+
it('attempt 1 (retry 2): delay in [0, 1000]', async () => {
|
|
291
|
+
const { backoffClock, delays } = makeInjectableSleep();
|
|
292
|
+
global.fetch = makeAlwaysFail(500);
|
|
293
|
+
const client = new NetworkClient_1.FetchNetworkClient({ maxRetries: 2, backoffClock });
|
|
294
|
+
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
295
|
+
expect(delays).toHaveLength(2);
|
|
296
|
+
expect(delays[1]).toBeGreaterThanOrEqual(0);
|
|
297
|
+
expect(delays[1]).toBeLessThanOrEqual(Math.min(NetworkClient_1.BACKOFF_CAP_MS, NetworkClient_1.BACKOFF_BASE_MS * Math.pow(NetworkClient_1.BACKOFF_MULTIPLIER, 1)));
|
|
298
|
+
});
|
|
299
|
+
it('attempt 2 (retry 3): delay in [0, 2000]', async () => {
|
|
300
|
+
const { backoffClock, delays } = makeInjectableSleep();
|
|
301
|
+
global.fetch = makeAlwaysFail(500);
|
|
302
|
+
const client = new NetworkClient_1.FetchNetworkClient({ maxRetries: NetworkClient_1.MAX_RETRY_ATTEMPTS, backoffClock });
|
|
303
|
+
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
304
|
+
expect(delays.length).toBeGreaterThanOrEqual(3);
|
|
305
|
+
expect(delays[2]).toBeGreaterThanOrEqual(0);
|
|
306
|
+
expect(delays[2]).toBeLessThanOrEqual(Math.min(NetworkClient_1.BACKOFF_CAP_MS, NetworkClient_1.BACKOFF_BASE_MS * Math.pow(NetworkClient_1.BACKOFF_MULTIPLIER, 2)));
|
|
307
|
+
});
|
|
308
|
+
it('attempt 3 (retry 4): delay in [0, 8000] — cap applies', async () => {
|
|
309
|
+
const { backoffClock, delays } = makeInjectableSleep();
|
|
310
|
+
global.fetch = makeAlwaysFail(500);
|
|
311
|
+
const client = new NetworkClient_1.FetchNetworkClient({ maxRetries: 4, backoffClock });
|
|
312
|
+
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
313
|
+
expect(delays.length).toBeGreaterThanOrEqual(4);
|
|
314
|
+
// base * 2^3 = 4000, which is < cap 8000, so cap = 8000 but actual max is 4000
|
|
315
|
+
expect(delays[3]).toBeGreaterThanOrEqual(0);
|
|
316
|
+
expect(delays[3]).toBeLessThanOrEqual(NetworkClient_1.BACKOFF_CAP_MS);
|
|
239
317
|
});
|
|
240
318
|
});
|
|
241
319
|
//# sourceMappingURL=RetryIntegration.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RetryIntegration.test.js","sourceRoot":"","sources":["../../../src/__tests__/networking/RetryIntegration.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RetryIntegration.test.js","sourceRoot":"","sources":["../../../src/__tests__/networking/RetryIntegration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -91,5 +91,14 @@ describe('InMemoryStorageProvider', () => {
|
|
|
91
91
|
// No TypeError because there is no type hint to validate against
|
|
92
92
|
await expect(provider.get(readKey)).resolves.toBe(42);
|
|
93
93
|
});
|
|
94
|
+
it('concurrent reads and writes do not throw', async () => {
|
|
95
|
+
const provider = new StorageProvider_1.InMemoryStorageProvider();
|
|
96
|
+
const key = (0, syzygy_foundation_rn_1.createStorageKey)('concurrent.key');
|
|
97
|
+
const ops = [
|
|
98
|
+
...Array.from({ length: 5 }, () => provider.set('value', key)),
|
|
99
|
+
...Array.from({ length: 5 }, () => provider.get(key)),
|
|
100
|
+
];
|
|
101
|
+
await expect(Promise.all(ops)).resolves.toBeDefined();
|
|
102
|
+
});
|
|
94
103
|
});
|
|
95
104
|
//# sourceMappingURL=StorageProvider.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageProvider.test.js","sourceRoot":"","sources":["../../../src/__tests__/persistence/StorageProvider.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StorageProvider.test.js","sourceRoot":"","sources":["../../../src/__tests__/persistence/StorageProvider.test.ts"],"names":[],"mappings":";;AAAA,+DAAwD;AAExD,uEAA4E;AAE5E,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAAS,UAAU,CAAC,CAAC;QACjD,MAAM,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAAS,OAAO,CAAC,CAAC;QAC9C,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5B,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAAU,MAAM,CAAC,CAAC;QAC9C,MAAM,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAA2B,KAAK,CAAC,CAAC;QAC9D,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAAS,SAAS,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAAS,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAAS,MAAM,CAAC,CAAC;QAC7C,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,MAAM,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAAS,MAAM,CAAC,CAAC;QAC7C,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,EAAE,GAAG,IAAA,uCAAgB,EAAS,GAAG,CAAC,CAAC;QACzC,MAAM,EAAE,GAAG,IAAA,uCAAgB,EAAS,GAAG,CAAC,CAAC;QACzC,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5B,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1B,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAC/C,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,EAAE,GAAG,IAAI,yCAAuB,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,IAAI,yCAAuB,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAAS,QAAQ,CAAC,CAAC;QAC/C,MAAM,EAAE,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,gDAAgD;QAChD,MAAM,MAAM,GAAG,IAAA,uCAAgB,EAAS,OAAO,CAAC,CAAC;QACjD,MAAM,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QAC3C,kFAAkF;QAClF,MAAM,MAAM,GAAG,IAAA,uCAAgB,EAAS,OAAO,EAAE,CAAC,CAAC,CAAC;QACpD,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC9D,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC;IAClG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAAS,OAAO,EAAE,CAAC,CAAC,CAAC;QACjD,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5B,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,+EAA+E;QAC/E,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAA,uCAAgB,EAAS,GAAG,CAAC,CAAC;QAC/C,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,IAAA,uCAAgB,EAAS,GAAG,CAAC,CAAC,CAAC,kBAAkB;QACjE,iEAAiE;QACjE,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,QAAQ,GAAG,IAAI,yCAAuB,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAA,uCAAgB,EAAS,gBAAgB,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG;YACV,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC9D,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SACtD,CAAC;QACF,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -41,6 +41,7 @@ export declare class NodeDeviceProvider implements DeviceProvider {
|
|
|
41
41
|
private readonly _appVersion;
|
|
42
42
|
private readonly _isSimulator;
|
|
43
43
|
private _cachedDeviceId;
|
|
44
|
+
private _pendingId;
|
|
44
45
|
constructor(options: NodeDeviceProviderOptions);
|
|
45
46
|
/**
|
|
46
47
|
* Returns the persistent device ID, generating and storing one on first
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceProvider.d.ts","sourceRoot":"","sources":["../../src/deviceservices/DeviceProvider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AA0B5D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAQD,8CAA8C;AAC9C,MAAM,WAAW,yBAAyB;IACxC,8DAA8D;IAC9D,OAAO,EAAE,eAAe,CAAC;IACzB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,eAAe,CAAqB;
|
|
1
|
+
{"version":3,"file":"DeviceProvider.d.ts","sourceRoot":"","sources":["../../src/deviceservices/DeviceProvider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AA0B5D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAQD,8CAA8C;AAC9C,MAAM,WAAW,yBAAyB;IACxC,8DAA8D;IAC9D,OAAO,EAAE,eAAe,CAAC;IACzB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,UAAU,CAAgC;gBAEtC,OAAO,EAAE,yBAAyB;IAM9C;;;OAGG;IACH,IAAI,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CAY9B;IAED,qBAAqB;IACrB,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;;OAGG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,kCAAkC;IAClC,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,qDAAqD;IACrD,IAAI,WAAW,IAAI,OAAO,CAEzB;YAIa,qBAAqB;CAWpC"}
|
|
@@ -36,6 +36,7 @@ const DEVICE_ID_KEY = (0, syzygy_foundation_rn_1.createStorageKey)('syzygy.devic
|
|
|
36
36
|
*/
|
|
37
37
|
class NodeDeviceProvider {
|
|
38
38
|
constructor(options) {
|
|
39
|
+
this._pendingId = null;
|
|
39
40
|
this.storage = options.storage;
|
|
40
41
|
this._appVersion = options.appVersion ?? readAppVersion();
|
|
41
42
|
this._isSimulator = options.isSimulator ?? false;
|
|
@@ -48,7 +49,14 @@ class NodeDeviceProvider {
|
|
|
48
49
|
if (this._cachedDeviceId !== undefined) {
|
|
49
50
|
return Promise.resolve(this._cachedDeviceId);
|
|
50
51
|
}
|
|
51
|
-
|
|
52
|
+
// Return existing in-flight promise to prevent concurrent callers from
|
|
53
|
+
// each generating their own UUID before the first write completes.
|
|
54
|
+
if (this._pendingId)
|
|
55
|
+
return this._pendingId;
|
|
56
|
+
this._pendingId = this._loadOrCreateDeviceId().finally(() => {
|
|
57
|
+
this._pendingId = null;
|
|
58
|
+
});
|
|
59
|
+
return this._pendingId;
|
|
52
60
|
}
|
|
53
61
|
/** Always `'rn'`. */
|
|
54
62
|
get platform() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceProvider.js","sourceRoot":"","sources":["../../src/deviceservices/DeviceProvider.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AAEpB,+DAAwD;AAGxD,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,YAAY;IACnB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QAC7E,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IACD,kCAAkC;IAClC,OAAO,sCAAsC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;QACnE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QAC1C,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC;AA6BD,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,MAAM,aAAa,GAAG,IAAA,uCAAgB,EAAS,oBAAoB,CAAC,CAAC;AAYrE;;;;;GAKG;AACH,MAAa,kBAAkB;
|
|
1
|
+
{"version":3,"file":"DeviceProvider.js","sourceRoot":"","sources":["../../src/deviceservices/DeviceProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,12 +34,22 @@ export interface RequestInterceptor {
|
|
|
34
34
|
* @param ms Milliseconds to sleep.
|
|
35
35
|
*/
|
|
36
36
|
export type BackoffClock = (ms: number) => Promise<void>;
|
|
37
|
+
/** Base delay in milliseconds for exponential back-off. */
|
|
38
|
+
export declare const BACKOFF_BASE_MS = 500;
|
|
39
|
+
/** Multiplier applied to the base delay on each successive attempt. */
|
|
40
|
+
export declare const BACKOFF_MULTIPLIER = 2;
|
|
41
|
+
/** Maximum delay cap in milliseconds for any single back-off sleep. */
|
|
42
|
+
export declare const BACKOFF_CAP_MS = 8000;
|
|
43
|
+
/** Maximum number of retry attempts before giving up. */
|
|
44
|
+
export declare const MAX_RETRY_ATTEMPTS = 3;
|
|
37
45
|
/** Configuration options for {@link FetchNetworkClient}. */
|
|
38
46
|
export interface FetchNetworkClientOptions {
|
|
39
|
-
/** Maximum number of automatic retries on server errors (5xx). Default:
|
|
47
|
+
/** Maximum number of automatic retries on server errors (5xx). Default: {@link MAX_RETRY_ATTEMPTS}. */
|
|
40
48
|
maxRetries?: number;
|
|
41
|
-
/** Base delay (ms) for exponential back-off. Default:
|
|
49
|
+
/** Base delay (ms) for exponential back-off. Default: {@link BACKOFF_BASE_MS}. */
|
|
42
50
|
retryBaseDelayMs?: number;
|
|
51
|
+
/** Cap (ms) for exponential back-off. Default: {@link BACKOFF_CAP_MS}. */
|
|
52
|
+
retryCapMs?: number;
|
|
43
53
|
/** Interceptors applied to every request before dispatch. */
|
|
44
54
|
interceptors?: RequestInterceptor[];
|
|
45
55
|
/**
|
|
@@ -68,6 +78,7 @@ export interface FetchNetworkClientOptions {
|
|
|
68
78
|
export declare class FetchNetworkClient implements NetworkClientProtocol {
|
|
69
79
|
private readonly maxRetries;
|
|
70
80
|
private readonly retryBaseDelayMs;
|
|
81
|
+
private readonly retryCapMs;
|
|
71
82
|
private readonly interceptors;
|
|
72
83
|
private readonly backoffClock;
|
|
73
84
|
private readonly logger?;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkClient.d.ts","sourceRoot":"","sources":["../../src/networking/NetworkClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAM5E;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,kBAAkB;IAClB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,kBAAkB;IAClB,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,kBAAkB;IAClB,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC;gBAG/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EACrB,QAAQ,GAAE,mBAA+C,EACzD,eAAe,CAAC,EAAE,KAAK;CAQ1B;AAMD;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC9E;AAMD;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"NetworkClient.d.ts","sourceRoot":"","sources":["../../src/networking/NetworkClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAM5E;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,kBAAkB;IAClB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,kBAAkB;IAClB,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,kBAAkB;IAClB,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC;gBAG/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EACrB,QAAQ,GAAE,mBAA+C,EACzD,eAAe,CAAC,EAAE,KAAK;CAQ1B;AAMD;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC9E;AAMD;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAOzD,2DAA2D;AAC3D,eAAO,MAAM,eAAe,MAAM,CAAC;AACnC,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,IAAM,CAAC;AACtC,uEAAuE;AACvE,eAAO,MAAM,cAAc,OAAO,CAAC;AACnC,yDAAyD;AACzD,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,4DAA4D;AAC5D,MAAM,WAAW,yBAAyB;IACxC,uGAAuG;IACvG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,YAAW,qBAAqB;IAC9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAiB;IACzC,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,GAAE,yBAA8B;IASnD;;;;;OAKG;IACH,OAAO,IAAI,IAAI;IAIf;;;;;;;;OAQG;IACG,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;YA6ElD,YAAY;CAoE3B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FetchNetworkClient = exports.NetworkError = void 0;
|
|
3
|
+
exports.FetchNetworkClient = exports.MAX_RETRY_ATTEMPTS = exports.BACKOFF_CAP_MS = exports.BACKOFF_MULTIPLIER = exports.BACKOFF_BASE_MS = exports.NetworkError = void 0;
|
|
4
4
|
const syzygy_foundation_rn_1 = require("syzygy-foundation-rn");
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
// NetworkError — local SyzygyError implementation
|
|
@@ -19,6 +19,18 @@ class NetworkError extends Error {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
exports.NetworkError = NetworkError;
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Canonical backoff policy (all 4 platforms must match)
|
|
24
|
+
// delay = random(0, min(cap, base * multiplier^attempt))
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/** Base delay in milliseconds for exponential back-off. */
|
|
27
|
+
exports.BACKOFF_BASE_MS = 500;
|
|
28
|
+
/** Multiplier applied to the base delay on each successive attempt. */
|
|
29
|
+
exports.BACKOFF_MULTIPLIER = 2.0;
|
|
30
|
+
/** Maximum delay cap in milliseconds for any single back-off sleep. */
|
|
31
|
+
exports.BACKOFF_CAP_MS = 8000;
|
|
32
|
+
/** Maximum number of retry attempts before giving up. */
|
|
33
|
+
exports.MAX_RETRY_ATTEMPTS = 3;
|
|
22
34
|
/**
|
|
23
35
|
* Fetch-based implementation of {@link NetworkClientProtocol}.
|
|
24
36
|
*
|
|
@@ -32,8 +44,9 @@ exports.NetworkError = NetworkError;
|
|
|
32
44
|
class FetchNetworkClient {
|
|
33
45
|
constructor(options = {}) {
|
|
34
46
|
this._disposed = false;
|
|
35
|
-
this.maxRetries = options.maxRetries ??
|
|
36
|
-
this.retryBaseDelayMs = options.retryBaseDelayMs ??
|
|
47
|
+
this.maxRetries = options.maxRetries ?? exports.MAX_RETRY_ATTEMPTS;
|
|
48
|
+
this.retryBaseDelayMs = options.retryBaseDelayMs ?? exports.BACKOFF_BASE_MS;
|
|
49
|
+
this.retryCapMs = options.retryCapMs ?? exports.BACKOFF_CAP_MS;
|
|
37
50
|
this.interceptors = options.interceptors ?? [];
|
|
38
51
|
this.backoffClock = options.backoffClock ?? defaultBackoffClock;
|
|
39
52
|
this.logger = options.logger;
|
|
@@ -77,7 +90,8 @@ class FetchNetworkClient {
|
|
|
77
90
|
let lastError;
|
|
78
91
|
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
79
92
|
if (attempt > 0) {
|
|
80
|
-
|
|
93
|
+
const cap = Math.min(this.retryCapMs, this.retryBaseDelayMs * Math.pow(exports.BACKOFF_MULTIPLIER, attempt - 1));
|
|
94
|
+
await this.backoffClock(Math.random() * cap);
|
|
81
95
|
}
|
|
82
96
|
try {
|
|
83
97
|
const response = await this._executeOnce(intercepted);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkClient.js","sourceRoot":"","sources":["../../src/networking/NetworkClient.ts"],"names":[],"mappings":";;;AAMA,+DAA4E;AAE5E,8EAA8E;AAC9E,kDAAkD;AAClD,8EAA8E;AAE9E;;;GAGG;AACH,MAAa,YAAa,SAAQ,KAAK;IAQrC,YACE,OAAe,EACf,IAAqB,EACrB,WAAgC,0CAAmB,CAAC,KAAK,EACzD,eAAuB;QAEvB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IACzC,CAAC;CACF;AApBD,oCAoBC;
|
|
1
|
+
{"version":3,"file":"NetworkClient.js","sourceRoot":"","sources":["../../src/networking/NetworkClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,6 +23,10 @@ export declare class InMemoryStorageProvider implements StorageProvider {
|
|
|
23
23
|
/**
|
|
24
24
|
* Serialises `value` as JSON and persists it under `key`.
|
|
25
25
|
*
|
|
26
|
+
* @param value - The value to store (NOTE: value comes before key —
|
|
27
|
+
* this matches the Foundation contract. See Foundation v1.2.0
|
|
28
|
+
* for potential API alignment.)
|
|
29
|
+
* @param key - The storage key
|
|
26
30
|
* @typeParam T The value type.
|
|
27
31
|
*/
|
|
28
32
|
set<T>(value: T, key: StorageKey<T>): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageProvider.d.ts","sourceRoot":"","sources":["../../src/persistence/StorageProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IAC7D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD;;;;;OAKG;IACG,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IA0BxD
|
|
1
|
+
{"version":3,"file":"StorageProvider.d.ts","sourceRoot":"","sources":["../../src/persistence/StorageProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IAC7D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD;;;;;OAKG;IACG,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IA0BxD;;;;;;;;OAQG;IACG,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD;;;;OAIG;IACG,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -46,6 +46,10 @@ class InMemoryStorageProvider {
|
|
|
46
46
|
/**
|
|
47
47
|
* Serialises `value` as JSON and persists it under `key`.
|
|
48
48
|
*
|
|
49
|
+
* @param value - The value to store (NOTE: value comes before key —
|
|
50
|
+
* this matches the Foundation contract. See Foundation v1.2.0
|
|
51
|
+
* for potential API alignment.)
|
|
52
|
+
* @param key - The storage key
|
|
49
53
|
* @typeParam T The value type.
|
|
50
54
|
*/
|
|
51
55
|
async set(value, key) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageProvider.js","sourceRoot":"","sources":["../../src/persistence/StorageProvider.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;GAWG;AACH,MAAa,uBAAuB;IAApC;QACmB,UAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"StorageProvider.js","sourceRoot":"","sources":["../../src/persistence/StorageProvider.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;GAWG;AACH,MAAa,uBAAuB;IAApC;QACmB,UAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IA8DrD,CAAC;IA5DC;;;;;OAKG;IACH,KAAK,CAAC,GAAG,CAAI,GAAkB;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,GAAG,CAAC,YAAY,CAAC;QAE/C,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,SAAS,CACjB,yBAAyB,GAAG,CAAC,UAAU,sDAAsD,CAC9F,CAAC;QACJ,CAAC;QAED,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACnC,MAAM,YAAY,GAAG,OAAO,GAAG,CAAC,YAAY,CAAC;YAC7C,MAAM,UAAU,GAAG,OAAO,MAAM,CAAC;YACjC,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;gBAChC,MAAM,IAAI,SAAS,CACjB,yBAAyB,GAAG,CAAC,UAAU,6BAA6B,UAAU,eAAe,YAAY,iBAAiB,CAC3H,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,MAAW,CAAC;IACrB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,GAAG,CAAI,KAAQ,EAAE,GAAkB;QACvC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACxD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAI,GAAkB;QAChC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF;AA/DD,0DA+DC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "syzygy-services-rn",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Concrete I/O service implementations for the Syzygy React Native ecosystem",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"prepare": "npm run build"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"syzygy-foundation-rn": "^1.
|
|
30
|
+
"syzygy-foundation-rn": "^1.2.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@react-native-community/eslint-plugin": "^1.3.0",
|
|
@@ -72,4 +72,11 @@ describe('NodeDeviceProvider', () => {
|
|
|
72
72
|
const [id1, id2] = await Promise.all([p1.deviceId, p2.deviceId]);
|
|
73
73
|
expect(id1).not.toBe(id2);
|
|
74
74
|
});
|
|
75
|
+
|
|
76
|
+
it('concurrent getDeviceId calls all return same UUID', async () => {
|
|
77
|
+
const storage = new InMemoryStorageProvider();
|
|
78
|
+
const provider = new NodeDeviceProvider({ storage });
|
|
79
|
+
const results = await Promise.all(Array.from({ length: 10 }, () => provider.deviceId));
|
|
80
|
+
expect(new Set(results).size).toBe(1);
|
|
81
|
+
});
|
|
75
82
|
});
|
|
@@ -6,7 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { createNetworkRequest } from 'syzygy-foundation-rn';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
BACKOFF_BASE_MS,
|
|
11
|
+
BACKOFF_CAP_MS,
|
|
12
|
+
BACKOFF_MULTIPLIER,
|
|
13
|
+
FetchNetworkClient,
|
|
14
|
+
MAX_RETRY_ATTEMPTS,
|
|
15
|
+
} from '../../networking/NetworkClient';
|
|
10
16
|
import type { BackoffClock } from '../../networking/NetworkClient';
|
|
11
17
|
|
|
12
18
|
// ---------------------------------------------------------------------------
|
|
@@ -123,30 +129,30 @@ describe('FetchNetworkClient — retry integration', () => {
|
|
|
123
129
|
expect(mockFetch).toHaveBeenCalledTimes(maxRetries + 1);
|
|
124
130
|
});
|
|
125
131
|
|
|
126
|
-
it('exponential backoff: delay
|
|
132
|
+
it('exponential backoff: delay grows with each retry (jitter range check)', async () => {
|
|
127
133
|
const baseDelay = 100;
|
|
134
|
+
const capMs = 8000;
|
|
128
135
|
const maxRetries = 3;
|
|
129
136
|
const mockFetch = makeAlwaysFail(500);
|
|
130
137
|
global.fetch = mockFetch;
|
|
131
138
|
|
|
132
|
-
//
|
|
133
|
-
// attempt 1 →
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
baseDelay * Math.pow(2,
|
|
139
|
+
// Canonical policy: delay = random(0, min(cap, base * 2^attempt))
|
|
140
|
+
// attempt 1 → [0, min(cap, base*2^0)] = [0, 100]
|
|
141
|
+
// attempt 2 → [0, min(cap, base*2^1)] = [0, 200]
|
|
142
|
+
// attempt 3 → [0, min(cap, base*2^2)] = [0, 400]
|
|
143
|
+
const expectedCaps = [
|
|
144
|
+
Math.min(capMs, baseDelay * Math.pow(2, 0)),
|
|
145
|
+
Math.min(capMs, baseDelay * Math.pow(2, 1)),
|
|
146
|
+
Math.min(capMs, baseDelay * Math.pow(2, 2)),
|
|
138
147
|
];
|
|
139
148
|
|
|
140
|
-
// Verify via the observable: stub setTimeout so retries run instantly,
|
|
141
|
-
// capture only delays in the [baseDelay..] range (exclude the per-request
|
|
142
|
-
// abort timeout which is set to timeoutSeconds * 1000 = 30000 ms).
|
|
143
149
|
const capturedDelays: number[] = [];
|
|
144
150
|
jest
|
|
145
151
|
.spyOn(global, 'setTimeout')
|
|
146
152
|
.mockImplementation(
|
|
147
153
|
(fn: Parameters<typeof setTimeout>[0], ms?: number, ...args: unknown[]) => {
|
|
148
154
|
const delay = ms ?? 0;
|
|
149
|
-
if (delay
|
|
155
|
+
if (delay >= 0 && delay <= baseDelay * 10) {
|
|
150
156
|
// Only capture retry-range delays
|
|
151
157
|
capturedDelays.push(delay);
|
|
152
158
|
}
|
|
@@ -156,10 +162,18 @@ describe('FetchNetworkClient — retry integration', () => {
|
|
|
156
162
|
},
|
|
157
163
|
);
|
|
158
164
|
|
|
159
|
-
const client = new FetchNetworkClient({
|
|
165
|
+
const client = new FetchNetworkClient({
|
|
166
|
+
maxRetries,
|
|
167
|
+
retryBaseDelayMs: baseDelay,
|
|
168
|
+
retryCapMs: capMs,
|
|
169
|
+
});
|
|
160
170
|
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
161
171
|
|
|
162
|
-
expect(capturedDelays).
|
|
172
|
+
expect(capturedDelays).toHaveLength(maxRetries);
|
|
173
|
+
capturedDelays.forEach((delay, i) => {
|
|
174
|
+
expect(delay).toBeGreaterThanOrEqual(0);
|
|
175
|
+
expect(delay).toBeLessThanOrEqual(expectedCaps[i]);
|
|
176
|
+
});
|
|
163
177
|
});
|
|
164
178
|
|
|
165
179
|
it('zero maxRetries means no retry — only one attempt', async () => {
|
|
@@ -197,9 +211,10 @@ describe('FetchNetworkClient — injectable BackoffClock (deterministic backoff)
|
|
|
197
211
|
jest.restoreAllMocks();
|
|
198
212
|
});
|
|
199
213
|
|
|
200
|
-
it('injectable BackoffClock is called once per retry with
|
|
214
|
+
it('injectable BackoffClock is called once per retry with jitter delays in expected range', async () => {
|
|
201
215
|
const { backoffClock, delays } = makeInjectableSleep();
|
|
202
216
|
const baseDelay = 100;
|
|
217
|
+
const capMs = 8000;
|
|
203
218
|
const maxRetries = 3;
|
|
204
219
|
const mockFetch = makeAlwaysFail(500);
|
|
205
220
|
global.fetch = mockFetch;
|
|
@@ -207,17 +222,23 @@ describe('FetchNetworkClient — injectable BackoffClock (deterministic backoff)
|
|
|
207
222
|
const client = new FetchNetworkClient({
|
|
208
223
|
maxRetries,
|
|
209
224
|
retryBaseDelayMs: baseDelay,
|
|
225
|
+
retryCapMs: capMs,
|
|
210
226
|
backoffClock,
|
|
211
227
|
});
|
|
212
228
|
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
213
229
|
|
|
214
230
|
// backoffClock called once per retry (not for the initial attempt)
|
|
215
231
|
expect(delays).toHaveLength(maxRetries);
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
baseDelay * Math.pow(2,
|
|
219
|
-
baseDelay * Math.pow(2,
|
|
220
|
-
|
|
232
|
+
// Canonical policy: delay = random(0, min(cap, base * 2^attempt))
|
|
233
|
+
const expectedCaps = [
|
|
234
|
+
Math.min(capMs, baseDelay * Math.pow(2, 0)), // [0, 100]
|
|
235
|
+
Math.min(capMs, baseDelay * Math.pow(2, 1)), // [0, 200]
|
|
236
|
+
Math.min(capMs, baseDelay * Math.pow(2, 2)), // [0, 400]
|
|
237
|
+
];
|
|
238
|
+
delays.forEach((delay, i) => {
|
|
239
|
+
expect(delay).toBeGreaterThanOrEqual(0);
|
|
240
|
+
expect(delay).toBeLessThanOrEqual(expectedCaps[i]);
|
|
241
|
+
});
|
|
221
242
|
});
|
|
222
243
|
|
|
223
244
|
it('injectable BackoffClock is NOT called on first attempt (no prior failure)', async () => {
|
|
@@ -247,11 +268,13 @@ describe('FetchNetworkClient — injectable BackoffClock (deterministic backoff)
|
|
|
247
268
|
it('injectable BackoffClock records partial delays when server recovers mid-retry', async () => {
|
|
248
269
|
const { backoffClock, delays } = makeInjectableSleep();
|
|
249
270
|
const baseDelay = 50;
|
|
271
|
+
const capMs = 8000;
|
|
250
272
|
global.fetch = makeRecoverAfter(2);
|
|
251
273
|
|
|
252
274
|
const client = new FetchNetworkClient({
|
|
253
275
|
maxRetries: 3,
|
|
254
276
|
retryBaseDelayMs: baseDelay,
|
|
277
|
+
retryCapMs: capMs,
|
|
255
278
|
backoffClock,
|
|
256
279
|
});
|
|
257
280
|
const response = await client.execute(makeRequest());
|
|
@@ -259,12 +282,21 @@ describe('FetchNetworkClient — injectable BackoffClock (deterministic backoff)
|
|
|
259
282
|
expect(response.statusCode).toBe(200);
|
|
260
283
|
// 2 failures → 2 sleeps
|
|
261
284
|
expect(delays).toHaveLength(2);
|
|
262
|
-
|
|
285
|
+
// Canonical policy: delay = random(0, min(cap, base * 2^attempt))
|
|
286
|
+
const expectedCaps = [
|
|
287
|
+
Math.min(capMs, baseDelay * Math.pow(2, 0)), // [0, 50]
|
|
288
|
+
Math.min(capMs, baseDelay * Math.pow(2, 1)), // [0, 100]
|
|
289
|
+
];
|
|
290
|
+
delays.forEach((delay, i) => {
|
|
291
|
+
expect(delay).toBeGreaterThanOrEqual(0);
|
|
292
|
+
expect(delay).toBeLessThanOrEqual(expectedCaps[i]);
|
|
293
|
+
});
|
|
263
294
|
});
|
|
264
295
|
|
|
265
296
|
it('default BackoffClock (no injection) still works — setTimeout is used for retry delay', async () => {
|
|
266
297
|
// Stub setTimeout so the test runs fast; filter for retry-range delays only.
|
|
267
298
|
const baseDelay = 10;
|
|
299
|
+
const capMs = 8000;
|
|
268
300
|
const capturedDelays: number[] = [];
|
|
269
301
|
jest
|
|
270
302
|
.spyOn(global, 'setTimeout')
|
|
@@ -272,7 +304,7 @@ describe('FetchNetworkClient — injectable BackoffClock (deterministic backoff)
|
|
|
272
304
|
(fn: Parameters<typeof setTimeout>[0], ms?: number, ...args: unknown[]) => {
|
|
273
305
|
const d = ms ?? 0;
|
|
274
306
|
// Capture only the retry-range delay (not the per-request abort timeout)
|
|
275
|
-
if (d
|
|
307
|
+
if (d >= 0 && d <= baseDelay * 10) capturedDelays.push(d);
|
|
276
308
|
(fn as () => void)(...(args as []));
|
|
277
309
|
return 0 as unknown as ReturnType<typeof setTimeout>;
|
|
278
310
|
},
|
|
@@ -282,11 +314,75 @@ describe('FetchNetworkClient — injectable BackoffClock (deterministic backoff)
|
|
|
282
314
|
global.fetch = mockFetch;
|
|
283
315
|
|
|
284
316
|
// No backoffClock injected — uses default setTimeout-backed delay
|
|
285
|
-
const client = new FetchNetworkClient({
|
|
317
|
+
const client = new FetchNetworkClient({
|
|
318
|
+
maxRetries: 1,
|
|
319
|
+
retryBaseDelayMs: baseDelay,
|
|
320
|
+
retryCapMs: capMs,
|
|
321
|
+
});
|
|
286
322
|
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
287
323
|
|
|
288
|
-
// 1 retry → 1 delay recorded in the retry-range
|
|
324
|
+
// 1 retry → 1 delay recorded in the retry-range (jittered: [0, min(cap, base)])
|
|
289
325
|
expect(capturedDelays).toHaveLength(1);
|
|
290
|
-
expect(capturedDelays[0]).
|
|
326
|
+
expect(capturedDelays[0]).toBeGreaterThanOrEqual(0);
|
|
327
|
+
expect(capturedDelays[0]).toBeLessThanOrEqual(Math.min(capMs, baseDelay));
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// ---------------------------------------------------------------------------
|
|
332
|
+
// Canonical backoff policy contract assertions
|
|
333
|
+
// Verifies the cross-platform backoff contract:
|
|
334
|
+
// delay = random(0, min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * BACKOFF_MULTIPLIER^attempt))
|
|
335
|
+
// ---------------------------------------------------------------------------
|
|
336
|
+
|
|
337
|
+
describe('Canonical backoff policy — range assertions', () => {
|
|
338
|
+
afterEach(() => {
|
|
339
|
+
jest.restoreAllMocks();
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it('attempt 0 (retry 1): delay in [0, 500]', async () => {
|
|
343
|
+
const { backoffClock, delays } = makeInjectableSleep();
|
|
344
|
+
global.fetch = makeAlwaysFail(500);
|
|
345
|
+
const client = new FetchNetworkClient({ maxRetries: 1, backoffClock });
|
|
346
|
+
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
347
|
+
expect(delays).toHaveLength(1);
|
|
348
|
+
expect(delays[0]).toBeGreaterThanOrEqual(0);
|
|
349
|
+
expect(delays[0]).toBeLessThanOrEqual(
|
|
350
|
+
Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * Math.pow(BACKOFF_MULTIPLIER, 0)),
|
|
351
|
+
);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
it('attempt 1 (retry 2): delay in [0, 1000]', async () => {
|
|
355
|
+
const { backoffClock, delays } = makeInjectableSleep();
|
|
356
|
+
global.fetch = makeAlwaysFail(500);
|
|
357
|
+
const client = new FetchNetworkClient({ maxRetries: 2, backoffClock });
|
|
358
|
+
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
359
|
+
expect(delays).toHaveLength(2);
|
|
360
|
+
expect(delays[1]).toBeGreaterThanOrEqual(0);
|
|
361
|
+
expect(delays[1]).toBeLessThanOrEqual(
|
|
362
|
+
Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * Math.pow(BACKOFF_MULTIPLIER, 1)),
|
|
363
|
+
);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
it('attempt 2 (retry 3): delay in [0, 2000]', async () => {
|
|
367
|
+
const { backoffClock, delays } = makeInjectableSleep();
|
|
368
|
+
global.fetch = makeAlwaysFail(500);
|
|
369
|
+
const client = new FetchNetworkClient({ maxRetries: MAX_RETRY_ATTEMPTS, backoffClock });
|
|
370
|
+
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
371
|
+
expect(delays.length).toBeGreaterThanOrEqual(3);
|
|
372
|
+
expect(delays[2]).toBeGreaterThanOrEqual(0);
|
|
373
|
+
expect(delays[2]).toBeLessThanOrEqual(
|
|
374
|
+
Math.min(BACKOFF_CAP_MS, BACKOFF_BASE_MS * Math.pow(BACKOFF_MULTIPLIER, 2)),
|
|
375
|
+
);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
it('attempt 3 (retry 4): delay in [0, 8000] — cap applies', async () => {
|
|
379
|
+
const { backoffClock, delays } = makeInjectableSleep();
|
|
380
|
+
global.fetch = makeAlwaysFail(500);
|
|
381
|
+
const client = new FetchNetworkClient({ maxRetries: 4, backoffClock });
|
|
382
|
+
await expect(client.execute(makeRequest())).rejects.toThrow();
|
|
383
|
+
expect(delays.length).toBeGreaterThanOrEqual(4);
|
|
384
|
+
// base * 2^3 = 4000, which is < cap 8000, so cap = 8000 but actual max is 4000
|
|
385
|
+
expect(delays[3]).toBeGreaterThanOrEqual(0);
|
|
386
|
+
expect(delays[3]).toBeLessThanOrEqual(BACKOFF_CAP_MS);
|
|
291
387
|
});
|
|
292
388
|
});
|
|
@@ -103,4 +103,14 @@ describe('InMemoryStorageProvider', () => {
|
|
|
103
103
|
// No TypeError because there is no type hint to validate against
|
|
104
104
|
await expect(provider.get(readKey)).resolves.toBe(42);
|
|
105
105
|
});
|
|
106
|
+
|
|
107
|
+
it('concurrent reads and writes do not throw', async () => {
|
|
108
|
+
const provider = new InMemoryStorageProvider();
|
|
109
|
+
const key = createStorageKey<string>('concurrent.key');
|
|
110
|
+
const ops = [
|
|
111
|
+
...Array.from({ length: 5 }, () => provider.set('value', key)),
|
|
112
|
+
...Array.from({ length: 5 }, () => provider.get(key)),
|
|
113
|
+
];
|
|
114
|
+
await expect(Promise.all(ops)).resolves.toBeDefined();
|
|
115
|
+
});
|
|
106
116
|
});
|
|
@@ -77,6 +77,7 @@ export class NodeDeviceProvider implements DeviceProvider {
|
|
|
77
77
|
private readonly _appVersion: string;
|
|
78
78
|
private readonly _isSimulator: boolean;
|
|
79
79
|
private _cachedDeviceId: string | undefined;
|
|
80
|
+
private _pendingId: Promise<string> | null = null;
|
|
80
81
|
|
|
81
82
|
constructor(options: NodeDeviceProviderOptions) {
|
|
82
83
|
this.storage = options.storage;
|
|
@@ -92,7 +93,14 @@ export class NodeDeviceProvider implements DeviceProvider {
|
|
|
92
93
|
if (this._cachedDeviceId !== undefined) {
|
|
93
94
|
return Promise.resolve(this._cachedDeviceId);
|
|
94
95
|
}
|
|
95
|
-
|
|
96
|
+
// Return existing in-flight promise to prevent concurrent callers from
|
|
97
|
+
// each generating their own UUID before the first write completes.
|
|
98
|
+
if (this._pendingId) return this._pendingId;
|
|
99
|
+
|
|
100
|
+
this._pendingId = this._loadOrCreateDeviceId().finally(() => {
|
|
101
|
+
this._pendingId = null;
|
|
102
|
+
});
|
|
103
|
+
return this._pendingId;
|
|
96
104
|
}
|
|
97
105
|
|
|
98
106
|
/** Always `'rn'`. */
|
|
@@ -67,12 +67,28 @@ export interface RequestInterceptor {
|
|
|
67
67
|
*/
|
|
68
68
|
export type BackoffClock = (ms: number) => Promise<void>;
|
|
69
69
|
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Canonical backoff policy (all 4 platforms must match)
|
|
72
|
+
// delay = random(0, min(cap, base * multiplier^attempt))
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
/** Base delay in milliseconds for exponential back-off. */
|
|
76
|
+
export const BACKOFF_BASE_MS = 500;
|
|
77
|
+
/** Multiplier applied to the base delay on each successive attempt. */
|
|
78
|
+
export const BACKOFF_MULTIPLIER = 2.0;
|
|
79
|
+
/** Maximum delay cap in milliseconds for any single back-off sleep. */
|
|
80
|
+
export const BACKOFF_CAP_MS = 8000;
|
|
81
|
+
/** Maximum number of retry attempts before giving up. */
|
|
82
|
+
export const MAX_RETRY_ATTEMPTS = 3;
|
|
83
|
+
|
|
70
84
|
/** Configuration options for {@link FetchNetworkClient}. */
|
|
71
85
|
export interface FetchNetworkClientOptions {
|
|
72
|
-
/** Maximum number of automatic retries on server errors (5xx). Default:
|
|
86
|
+
/** Maximum number of automatic retries on server errors (5xx). Default: {@link MAX_RETRY_ATTEMPTS}. */
|
|
73
87
|
maxRetries?: number;
|
|
74
|
-
/** Base delay (ms) for exponential back-off. Default:
|
|
88
|
+
/** Base delay (ms) for exponential back-off. Default: {@link BACKOFF_BASE_MS}. */
|
|
75
89
|
retryBaseDelayMs?: number;
|
|
90
|
+
/** Cap (ms) for exponential back-off. Default: {@link BACKOFF_CAP_MS}. */
|
|
91
|
+
retryCapMs?: number;
|
|
76
92
|
/** Interceptors applied to every request before dispatch. */
|
|
77
93
|
interceptors?: RequestInterceptor[];
|
|
78
94
|
/**
|
|
@@ -102,14 +118,16 @@ export interface FetchNetworkClientOptions {
|
|
|
102
118
|
export class FetchNetworkClient implements NetworkClientProtocol {
|
|
103
119
|
private readonly maxRetries: number;
|
|
104
120
|
private readonly retryBaseDelayMs: number;
|
|
121
|
+
private readonly retryCapMs: number;
|
|
105
122
|
private readonly interceptors: RequestInterceptor[];
|
|
106
123
|
private readonly backoffClock: BackoffClock;
|
|
107
124
|
private readonly logger?: LoggerProtocol;
|
|
108
125
|
private _disposed = false;
|
|
109
126
|
|
|
110
127
|
constructor(options: FetchNetworkClientOptions = {}) {
|
|
111
|
-
this.maxRetries = options.maxRetries ??
|
|
112
|
-
this.retryBaseDelayMs = options.retryBaseDelayMs ??
|
|
128
|
+
this.maxRetries = options.maxRetries ?? MAX_RETRY_ATTEMPTS;
|
|
129
|
+
this.retryBaseDelayMs = options.retryBaseDelayMs ?? BACKOFF_BASE_MS;
|
|
130
|
+
this.retryCapMs = options.retryCapMs ?? BACKOFF_CAP_MS;
|
|
113
131
|
this.interceptors = options.interceptors ?? [];
|
|
114
132
|
this.backoffClock = options.backoffClock ?? defaultBackoffClock;
|
|
115
133
|
this.logger = options.logger;
|
|
@@ -164,7 +182,11 @@ export class FetchNetworkClient implements NetworkClientProtocol {
|
|
|
164
182
|
|
|
165
183
|
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
166
184
|
if (attempt > 0) {
|
|
167
|
-
|
|
185
|
+
const cap = Math.min(
|
|
186
|
+
this.retryCapMs,
|
|
187
|
+
this.retryBaseDelayMs * Math.pow(BACKOFF_MULTIPLIER, attempt - 1),
|
|
188
|
+
);
|
|
189
|
+
await this.backoffClock(Math.random() * cap);
|
|
168
190
|
}
|
|
169
191
|
try {
|
|
170
192
|
const response = await this._executeOnce(intercepted);
|
|
@@ -50,6 +50,10 @@ export class InMemoryStorageProvider implements StorageProvider {
|
|
|
50
50
|
/**
|
|
51
51
|
* Serialises `value` as JSON and persists it under `key`.
|
|
52
52
|
*
|
|
53
|
+
* @param value - The value to store (NOTE: value comes before key —
|
|
54
|
+
* this matches the Foundation contract. See Foundation v1.2.0
|
|
55
|
+
* for potential API alignment.)
|
|
56
|
+
* @param key - The storage key
|
|
53
57
|
* @typeParam T The value type.
|
|
54
58
|
*/
|
|
55
59
|
async set<T>(value: T, key: StorageKey<T>): Promise<void> {
|
package/syzygy.yml
CHANGED