@buoy-gg/network 7.0.41 → 7.0.42
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/README.md +11 -85
- package/lib/commonjs/index.js +1 -332
- package/lib/commonjs/index.web.js +1 -420
- package/lib/commonjs/network/components/DataViewer.web.js +1 -879
- package/lib/commonjs/network/components/NetworkCopyScreen.web.js +1 -48
- package/lib/commonjs/network/components/NetworkCopySettingsView.js +27 -755
- package/lib/commonjs/network/components/NetworkCopySettingsView.web.js +14 -1242
- package/lib/commonjs/network/components/NetworkDetailScreen.web.js +1 -101
- package/lib/commonjs/network/components/NetworkDetailStepper.js +1 -108
- package/lib/commonjs/network/components/NetworkDetailStepper.web.js +1 -298
- package/lib/commonjs/network/components/NetworkEventDetailView.js +15 -1130
- package/lib/commonjs/network/components/NetworkEventDetailView.web.js +15 -1484
- package/lib/commonjs/network/components/NetworkEventItemCompact.js +2 -401
- package/lib/commonjs/network/components/NetworkEventItemCompact.web.js +2 -820
- package/lib/commonjs/network/components/NetworkFilterScreen.web.js +1 -55
- package/lib/commonjs/network/components/NetworkFilterViewV3.js +1 -442
- package/lib/commonjs/network/components/NetworkFilterViewV3.web.js +1 -1310
- package/lib/commonjs/network/components/NetworkHeaderLive.js +1 -375
- package/lib/commonjs/network/components/NetworkHeaderLive.web.js +1 -623
- package/lib/commonjs/network/components/NetworkHeaderMenu.js +1 -190
- package/lib/commonjs/network/components/NetworkListScreen.js +1 -403
- package/lib/commonjs/network/components/NetworkListScreen.web.js +1 -624
- package/lib/commonjs/network/components/NetworkModal.js +1 -786
- package/lib/commonjs/network/components/NetworkNumberPrompt.js +1 -178
- package/lib/commonjs/network/components/NetworkNumberPrompt.web.js +1 -232
- package/lib/commonjs/network/components/NetworkOverrideEditor.js +1 -814
- package/lib/commonjs/network/components/NetworkOverrideEditor.web.js +1 -942
- package/lib/commonjs/network/components/NetworkOverrideHeaderButton.js +1 -107
- package/lib/commonjs/network/components/NetworkOverrideHeaderButton.web.js +1 -133
- package/lib/commonjs/network/components/NetworkOverridesButton.js +1 -90
- package/lib/commonjs/network/components/NetworkOverridesButton.web.js +1 -143
- package/lib/commonjs/network/components/NetworkOverridesScreen.js +1 -543
- package/lib/commonjs/network/components/NetworkOverridesScreen.web.js +1 -830
- package/lib/commonjs/network/components/NetworkSavedScreen.js +1 -226
- package/lib/commonjs/network/components/NetworkSavedScreen.web.js +1 -463
- package/lib/commonjs/network/components/NetworkUpgradeBanner.js +1 -76
- package/lib/commonjs/network/components/response-editor/Explorer.js +1 -973
- package/lib/commonjs/network/components/response-editor/Explorer.web.js +1 -1136
- package/lib/commonjs/network/components/response-editor/deleteNestedDataByPath.js +1 -56
- package/lib/commonjs/network/components/response-editor/editorContext.js +1 -33
- package/lib/commonjs/network/components/response-editor/updateNestedDataByPath.js +1 -61
- package/lib/commonjs/network/conditions/NetworkConditionsControl.js +1 -235
- package/lib/commonjs/network/conditions/NetworkConditionsControl.test.js +1 -136
- package/lib/commonjs/network/conditions/NetworkConditionsIcon.js +1 -33
- package/lib/commonjs/network/conditions/NetworkFloatingTool.js +1 -310
- package/lib/commonjs/network/conditions/NetworkFloatingTool.test.js +1 -219
- package/lib/commonjs/network/conditions/store.js +1 -75
- package/lib/commonjs/network/conditions/wait.js +1 -43
- package/lib/commonjs/network/conditions/xhr.js +1 -135
- package/lib/commonjs/network/hooks/useLiveNetworkEvent.js +1 -62
- package/lib/commonjs/network/hooks/useNetworkBadgeCounts.js +1 -83
- package/lib/commonjs/network/hooks/useNetworkEventList.js +1 -108
- package/lib/commonjs/network/hooks/useNetworkEvents.js +1 -318
- package/lib/commonjs/network/hooks/useNetworkHasMatches.js +1 -56
- package/lib/commonjs/network/hooks/useNetworkSaved.js +1 -38
- package/lib/commonjs/network/hooks/useNetworkSelection.js +1 -53
- package/lib/commonjs/network/hooks/useOverrideRules.js +1 -36
- package/lib/commonjs/network/hooks/useTickEveryMinute.js +1 -21
- package/lib/commonjs/network/overrides/applyToFetch.js +1 -80
- package/lib/commonjs/network/overrides/applyToXhr.js +2 -510
- package/lib/commonjs/network/overrides/engine.js +1 -93
- package/lib/commonjs/network/overrides/matchRule.js +1 -87
- package/lib/commonjs/network/overrides/overriddenRows.js +1 -37
- package/lib/commonjs/network/overrides/overrideRulesStore.js +1 -550
- package/lib/commonjs/network/overrides/presets.js +1 -70
- package/lib/commonjs/network/overrides/resolveOverride.js +1 -158
- package/lib/commonjs/network/overrides/types.js +1 -90
- package/lib/commonjs/network/sync/networkBodyResolver.js +1 -39
- package/lib/commonjs/network/sync/networkSyncAdapter.js +1 -882
- package/lib/commonjs/network/sync/overrideHonesty.release.test.js +1 -36
- package/lib/commonjs/network/types/index.js +1 -5
- package/lib/commonjs/network/utils/extractOperationName.js +1 -80
- package/lib/commonjs/network/utils/filterNetworkEvents.js +1 -96
- package/lib/commonjs/network/utils/formatGraphQLVariables.js +1 -219
- package/lib/commonjs/network/utils/formatting.js +1 -30
- package/lib/commonjs/network/utils/generateCurl.js +2 -71
- package/lib/commonjs/network/utils/generateNetworkCopyText.js +37 -166
- package/lib/commonjs/network/utils/httpCompletion.js +1 -37
- package/lib/commonjs/network/utils/networkEventStore.js +1 -411
- package/lib/commonjs/network/utils/networkListener.js +4 -1352
- package/lib/commonjs/network/utils/networkSavedStore.js +3 -577
- package/lib/commonjs/network/utils/networkSelectionStore.js +1 -193
- package/lib/commonjs/network/utils/realNow.js +1 -0
- package/lib/commonjs/network/utils/requestId.js +1 -16
- package/lib/commonjs/network/utils/resolveRequestUrl.js +1 -15
- package/lib/commonjs/network/utils/selectSavedEvents.js +1 -39
- package/lib/commonjs/network/utils/startNetworkCapture.js +1 -24
- package/lib/commonjs/network/utils/withPinnedFirst.js +1 -32
- package/lib/commonjs/preset.js +1 -93
- package/lib/module/index.js +1 -104
- package/lib/module/index.web.js +1 -82
- package/lib/module/network/components/DataViewer.web.js +1 -875
- package/lib/module/network/components/NetworkCopyScreen.web.js +1 -44
- package/lib/module/network/components/NetworkCopySettingsView.js +27 -750
- package/lib/module/network/components/NetworkCopySettingsView.web.js +14 -1237
- package/lib/module/network/components/NetworkDetailScreen.web.js +1 -97
- package/lib/module/network/components/NetworkDetailStepper.js +1 -104
- package/lib/module/network/components/NetworkDetailStepper.web.js +1 -296
- package/lib/module/network/components/NetworkEventDetailView.js +15 -1129
- package/lib/module/network/components/NetworkEventDetailView.web.js +15 -1482
- package/lib/module/network/components/NetworkEventItemCompact.js +2 -398
- package/lib/module/network/components/NetworkEventItemCompact.web.js +2 -818
- package/lib/module/network/components/NetworkFilterScreen.web.js +1 -51
- package/lib/module/network/components/NetworkFilterViewV3.js +1 -438
- package/lib/module/network/components/NetworkFilterViewV3.web.js +1 -1306
- package/lib/module/network/components/NetworkHeaderLive.js +1 -366
- package/lib/module/network/components/NetworkHeaderLive.web.js +1 -617
- package/lib/module/network/components/NetworkHeaderMenu.js +1 -184
- package/lib/module/network/components/NetworkListScreen.js +1 -399
- package/lib/module/network/components/NetworkListScreen.web.js +1 -622
- package/lib/module/network/components/NetworkModal.js +1 -781
- package/lib/module/network/components/NetworkNumberPrompt.js +1 -174
- package/lib/module/network/components/NetworkNumberPrompt.web.js +1 -230
- package/lib/module/network/components/NetworkOverrideEditor.js +1 -811
- package/lib/module/network/components/NetworkOverrideEditor.web.js +1 -939
- package/lib/module/network/components/NetworkOverrideHeaderButton.js +1 -104
- package/lib/module/network/components/NetworkOverrideHeaderButton.web.js +1 -131
- package/lib/module/network/components/NetworkOverridesButton.js +1 -87
- package/lib/module/network/components/NetworkOverridesButton.web.js +1 -141
- package/lib/module/network/components/NetworkOverridesScreen.js +1 -539
- package/lib/module/network/components/NetworkOverridesScreen.web.js +1 -826
- package/lib/module/network/components/NetworkSavedScreen.js +1 -222
- package/lib/module/network/components/NetworkSavedScreen.web.js +1 -461
- package/lib/module/network/components/NetworkUpgradeBanner.js +1 -72
- package/lib/module/network/components/response-editor/Explorer.js +1 -972
- package/lib/module/network/components/response-editor/Explorer.web.js +1 -1133
- package/lib/module/network/components/response-editor/deleteNestedDataByPath.js +1 -51
- package/lib/module/network/components/response-editor/editorContext.js +1 -29
- package/lib/module/network/components/response-editor/updateNestedDataByPath.js +1 -56
- package/lib/module/network/conditions/NetworkConditionsControl.js +1 -231
- package/lib/module/network/conditions/NetworkConditionsControl.test.js +1 -135
- package/lib/module/network/conditions/NetworkConditionsIcon.js +1 -29
- package/lib/module/network/conditions/NetworkFloatingTool.js +1 -304
- package/lib/module/network/conditions/NetworkFloatingTool.test.js +1 -218
- package/lib/module/network/conditions/store.js +1 -65
- package/lib/module/network/conditions/wait.js +1 -38
- package/lib/module/network/conditions/xhr.js +1 -131
- package/lib/module/network/hooks/useLiveNetworkEvent.js +1 -58
- package/lib/module/network/hooks/useNetworkBadgeCounts.js +1 -79
- package/lib/module/network/hooks/useNetworkEventList.js +1 -104
- package/lib/module/network/hooks/useNetworkEvents.js +1 -314
- package/lib/module/network/hooks/useNetworkHasMatches.js +1 -52
- package/lib/module/network/hooks/useNetworkSaved.js +1 -34
- package/lib/module/network/hooks/useNetworkSelection.js +1 -46
- package/lib/module/network/hooks/useOverrideRules.js +1 -32
- package/lib/module/network/hooks/useTickEveryMinute.js +1 -11
- package/lib/module/network/overrides/applyToFetch.js +1 -72
- package/lib/module/network/overrides/applyToXhr.js +2 -502
- package/lib/module/network/overrides/engine.js +1 -85
- package/lib/module/network/overrides/matchRule.js +1 -81
- package/lib/module/network/overrides/overriddenRows.js +1 -33
- package/lib/module/network/overrides/overrideRulesStore.js +1 -547
- package/lib/module/network/overrides/presets.js +1 -65
- package/lib/module/network/overrides/resolveOverride.js +1 -152
- package/lib/module/network/overrides/types.js +1 -86
- package/lib/module/network/sync/networkBodyResolver.js +1 -34
- package/lib/module/network/sync/networkSyncAdapter.js +1 -880
- package/lib/module/network/sync/overrideHonesty.release.test.js +1 -35
- package/lib/module/network/types/index.js +1 -3
- package/lib/module/network/utils/extractOperationName.js +1 -76
- package/lib/module/network/utils/filterNetworkEvents.js +1 -92
- package/lib/module/network/utils/formatGraphQLVariables.js +1 -213
- package/lib/module/network/utils/formatting.js +1 -9
- package/lib/module/network/utils/generateCurl.js +2 -67
- package/lib/module/network/utils/generateNetworkCopyText.js +37 -162
- package/lib/module/network/utils/httpCompletion.js +1 -32
- package/lib/module/network/utils/networkEventStore.js +1 -409
- package/lib/module/network/utils/networkListener.js +4 -1341
- package/lib/module/network/utils/networkSavedStore.js +3 -572
- package/lib/module/network/utils/networkSelectionStore.js +1 -188
- package/lib/module/network/utils/realNow.js +1 -0
- package/lib/module/network/utils/requestId.js +1 -12
- package/lib/module/network/utils/resolveRequestUrl.js +1 -11
- package/lib/module/network/utils/selectSavedEvents.js +1 -35
- package/lib/module/network/utils/startNetworkCapture.js +1 -21
- package/lib/module/network/utils/withPinnedFirst.js +1 -28
- package/lib/module/preset.js +1 -91
- package/lib/typescript/network/overrides/engine.d.ts +1 -1
- package/lib/typescript/network/overrides/matchRule.d.ts +1 -1
- package/lib/typescript/network/overrides/resolveOverride.d.ts +2 -2
- package/lib/typescript/network/overrides/types.d.ts +9 -0
- package/lib/typescript/network/utils/networkListener.d.ts +11 -0
- package/lib/typescript/network/utils/realNow.d.ts +18 -0
- package/lib/web/index.mjs +73 -74
- package/package.json +2 -2
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/index.web.d.ts.map +0 -1
- package/lib/typescript/network/components/DataViewer.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkCopyScreen.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkCopySettingsView.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkCopySettingsView.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkDetailScreen.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkDetailStepper.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkDetailStepper.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkEventDetailView.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkEventDetailView.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkEventItemCompact.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkEventItemCompact.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkFilterScreen.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkFilterViewV3.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkFilterViewV3.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkHeaderLive.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkHeaderLive.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkHeaderMenu.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkListScreen.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkListScreen.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkModal.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkNumberPrompt.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkNumberPrompt.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkOverrideEditor.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkOverrideEditor.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkOverrideHeaderButton.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkOverrideHeaderButton.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkOverridesButton.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkOverridesButton.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkOverridesScreen.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkOverridesScreen.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkSavedScreen.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkSavedScreen.web.d.ts.map +0 -1
- package/lib/typescript/network/components/NetworkUpgradeBanner.d.ts.map +0 -1
- package/lib/typescript/network/components/response-editor/Explorer.d.ts.map +0 -1
- package/lib/typescript/network/components/response-editor/Explorer.web.d.ts.map +0 -1
- package/lib/typescript/network/components/response-editor/deleteNestedDataByPath.d.ts.map +0 -1
- package/lib/typescript/network/components/response-editor/editorContext.d.ts.map +0 -1
- package/lib/typescript/network/components/response-editor/updateNestedDataByPath.d.ts.map +0 -1
- package/lib/typescript/network/conditions/NetworkConditionsControl.d.ts.map +0 -1
- package/lib/typescript/network/conditions/NetworkConditionsControl.test.d.ts.map +0 -1
- package/lib/typescript/network/conditions/NetworkConditionsIcon.d.ts.map +0 -1
- package/lib/typescript/network/conditions/NetworkFloatingTool.d.ts.map +0 -1
- package/lib/typescript/network/conditions/NetworkFloatingTool.test.d.ts.map +0 -1
- package/lib/typescript/network/conditions/store.d.ts.map +0 -1
- package/lib/typescript/network/conditions/wait.d.ts.map +0 -1
- package/lib/typescript/network/conditions/xhr.d.ts.map +0 -1
- package/lib/typescript/network/hooks/useLiveNetworkEvent.d.ts.map +0 -1
- package/lib/typescript/network/hooks/useNetworkBadgeCounts.d.ts.map +0 -1
- package/lib/typescript/network/hooks/useNetworkEventList.d.ts.map +0 -1
- package/lib/typescript/network/hooks/useNetworkEvents.d.ts.map +0 -1
- package/lib/typescript/network/hooks/useNetworkHasMatches.d.ts.map +0 -1
- package/lib/typescript/network/hooks/useNetworkSaved.d.ts.map +0 -1
- package/lib/typescript/network/hooks/useNetworkSelection.d.ts.map +0 -1
- package/lib/typescript/network/hooks/useOverrideRules.d.ts.map +0 -1
- package/lib/typescript/network/hooks/useTickEveryMinute.d.ts.map +0 -1
- package/lib/typescript/network/overrides/applyToFetch.d.ts.map +0 -1
- package/lib/typescript/network/overrides/applyToXhr.d.ts.map +0 -1
- package/lib/typescript/network/overrides/engine.d.ts.map +0 -1
- package/lib/typescript/network/overrides/matchRule.d.ts.map +0 -1
- package/lib/typescript/network/overrides/overriddenRows.d.ts.map +0 -1
- package/lib/typescript/network/overrides/overrideRulesStore.d.ts.map +0 -1
- package/lib/typescript/network/overrides/presets.d.ts.map +0 -1
- package/lib/typescript/network/overrides/resolveOverride.d.ts.map +0 -1
- package/lib/typescript/network/overrides/types.d.ts.map +0 -1
- package/lib/typescript/network/sync/networkBodyResolver.d.ts.map +0 -1
- package/lib/typescript/network/sync/networkSyncAdapter.d.ts.map +0 -1
- package/lib/typescript/network/sync/overrideHonesty.release.test.d.ts.map +0 -1
- package/lib/typescript/network/types/index.d.ts.map +0 -1
- package/lib/typescript/network/utils/extractOperationName.d.ts.map +0 -1
- package/lib/typescript/network/utils/filterNetworkEvents.d.ts.map +0 -1
- package/lib/typescript/network/utils/formatGraphQLVariables.d.ts.map +0 -1
- package/lib/typescript/network/utils/formatting.d.ts.map +0 -1
- package/lib/typescript/network/utils/generateCurl.d.ts.map +0 -1
- package/lib/typescript/network/utils/generateNetworkCopyText.d.ts.map +0 -1
- package/lib/typescript/network/utils/httpCompletion.d.ts.map +0 -1
- package/lib/typescript/network/utils/networkEventStore.d.ts.map +0 -1
- package/lib/typescript/network/utils/networkListener.d.ts.map +0 -1
- package/lib/typescript/network/utils/networkSavedStore.d.ts.map +0 -1
- package/lib/typescript/network/utils/networkSelectionStore.d.ts.map +0 -1
- package/lib/typescript/network/utils/requestId.d.ts.map +0 -1
- package/lib/typescript/network/utils/resolveRequestUrl.d.ts.map +0 -1
- package/lib/typescript/network/utils/selectSavedEvents.d.ts.map +0 -1
- package/lib/typescript/network/utils/startNetworkCapture.d.ts.map +0 -1
- package/lib/typescript/network/utils/withPinnedFirst.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
|
@@ -1,51 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Deletes nested data by path
|
|
5
|
-
*
|
|
6
|
-
* @param {unknown} oldData Data to be updated
|
|
7
|
-
* @param {Array<string>} deletePath Path to the data to be deleted
|
|
8
|
-
* @returns newData without the deleted items by path
|
|
9
|
-
*/
|
|
10
|
-
export const deleteNestedDataByPath = (oldData, deletePath) => {
|
|
11
|
-
if (oldData instanceof Map) {
|
|
12
|
-
const newData = new Map(oldData);
|
|
13
|
-
if (deletePath.length === 1) {
|
|
14
|
-
newData.delete(deletePath[0]);
|
|
15
|
-
return newData;
|
|
16
|
-
}
|
|
17
|
-
const [head, ...tail] = deletePath;
|
|
18
|
-
newData.set(head, deleteNestedDataByPath(newData.get(head), tail));
|
|
19
|
-
return newData;
|
|
20
|
-
}
|
|
21
|
-
if (oldData instanceof Set) {
|
|
22
|
-
const setAsArray = deleteNestedDataByPath(Array.from(oldData), deletePath);
|
|
23
|
-
return new Set(setAsArray);
|
|
24
|
-
}
|
|
25
|
-
if (Array.isArray(oldData)) {
|
|
26
|
-
const newData = [...oldData];
|
|
27
|
-
if (deletePath.length === 1) {
|
|
28
|
-
return newData.filter((_, idx) => idx.toString() !== deletePath[0]);
|
|
29
|
-
}
|
|
30
|
-
const [head, ...tail] = deletePath;
|
|
31
|
-
|
|
32
|
-
// @ts-expect-error NAS
|
|
33
|
-
newData[head] = deleteNestedDataByPath(newData[head], tail);
|
|
34
|
-
return newData;
|
|
35
|
-
}
|
|
36
|
-
if (oldData instanceof Object) {
|
|
37
|
-
const newData = {
|
|
38
|
-
...oldData
|
|
39
|
-
};
|
|
40
|
-
if (deletePath.length === 1) {
|
|
41
|
-
// @ts-expect-error NAS
|
|
42
|
-
delete newData[deletePath[0]];
|
|
43
|
-
return newData;
|
|
44
|
-
}
|
|
45
|
-
const [head, ...tail] = deletePath;
|
|
46
|
-
// @ts-expect-error NAS
|
|
47
|
-
newData[head] = deleteNestedDataByPath(newData[head], tail);
|
|
48
|
-
return newData;
|
|
49
|
-
}
|
|
50
|
-
return oldData;
|
|
51
|
-
};
|
|
1
|
+
"use strict";export const deleteNestedDataByPath=(t,r)=>{if(t instanceof Map){const n=new Map(t);if(r.length===1){n.delete(r[0]);return n}const[s,...i]=r;n.set(s,deleteNestedDataByPath(n.get(s),i));return n}if(t instanceof Set){const n=deleteNestedDataByPath(Array.from(t),r);return new Set(n)}if(Array.isArray(t)){const n=[...t];if(r.length===1){return n.filter((c,e)=>e.toString()!==r[0])}const[s,...i]=r;n[s]=deleteNestedDataByPath(n[s],i);return n}if(t instanceof Object){const n={...t};if(r.length===1){delete n[r[0]];return n}const[s,...i]=r;n[s]=deleteNestedDataByPath(n[s],i);return n}return t};
|
|
@@ -1,29 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { createContext, useContext } from "react";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* What the ported Explorer needs in place of React Query's cache.
|
|
7
|
-
*
|
|
8
|
-
* In the original, every edit ends at
|
|
9
|
-
* `queryClient.setQueryData(activeQuery.queryKey, newData)` and `activeQuery`
|
|
10
|
-
* doubles as the "is this editable" gate — so the whole tree is wired to one
|
|
11
|
-
* specific store. Here that becomes two values in context: the ROOT document
|
|
12
|
-
* (every op rebuilds the whole thing from the root, so each row needs it) and a
|
|
13
|
-
* single `onChange`.
|
|
14
|
-
*
|
|
15
|
-
* Context rather than props because Explorer recurses per node and already
|
|
16
|
-
* threads `activeQuery` down every level; swapping one drilled prop for another
|
|
17
|
-
* would have meant the same plumbing at every call site, and a row deep in a
|
|
18
|
-
* response is exactly where you don't want a missed prop.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
export const ResponseEditorContext = /*#__PURE__*/createContext(null);
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Null outside a provider, which is how the tree stays READ-ONLY by default —
|
|
25
|
-
* the same role `activeQuery === undefined` played in the original.
|
|
26
|
-
*/
|
|
27
|
-
export function useResponseEditor() {
|
|
28
|
-
return useContext(ResponseEditorContext);
|
|
29
|
-
}
|
|
1
|
+
"use strict";import{createContext as t,useContext as e}from"react";export const ResponseEditorContext=t(null);export function useResponseEditor(){return e(ResponseEditorContext)}
|
|
@@ -1,56 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* updates nested data by path
|
|
5
|
-
*
|
|
6
|
-
* @param {JsonValue} oldData Data to be updated
|
|
7
|
-
* @param {Array<string>} updatePath Path to the data to be updated
|
|
8
|
-
* @param {JsonValue} value New value
|
|
9
|
-
*/
|
|
10
|
-
export const updateNestedDataByPath = (oldData, updatePath, value) => {
|
|
11
|
-
if (updatePath.length === 0) {
|
|
12
|
-
return value;
|
|
13
|
-
}
|
|
14
|
-
if (oldData instanceof Map) {
|
|
15
|
-
const newData = new Map(oldData);
|
|
16
|
-
if (updatePath.length === 1) {
|
|
17
|
-
newData.set(updatePath[0], value);
|
|
18
|
-
return newData;
|
|
19
|
-
}
|
|
20
|
-
const [head, ...tail] = updatePath;
|
|
21
|
-
const currentValue = newData.get(head);
|
|
22
|
-
newData.set(head, updateNestedDataByPath(currentValue ?? null, tail, value));
|
|
23
|
-
return newData;
|
|
24
|
-
}
|
|
25
|
-
if (oldData instanceof Set) {
|
|
26
|
-
const setAsArray = updateNestedDataByPath(Array.from(oldData), updatePath, value);
|
|
27
|
-
return new Set(Array.isArray(setAsArray) ? setAsArray : []);
|
|
28
|
-
}
|
|
29
|
-
if (Array.isArray(oldData)) {
|
|
30
|
-
const newData = [...oldData];
|
|
31
|
-
if (updatePath.length === 1) {
|
|
32
|
-
// @ts-expect-error NAS
|
|
33
|
-
newData[updatePath[0]] = value;
|
|
34
|
-
return newData;
|
|
35
|
-
}
|
|
36
|
-
const [head, ...tail] = updatePath;
|
|
37
|
-
// @ts-expect-error NAS
|
|
38
|
-
newData[head] = updateNestedDataByPath(newData[head], tail, value);
|
|
39
|
-
return newData;
|
|
40
|
-
}
|
|
41
|
-
if (oldData instanceof Object) {
|
|
42
|
-
const newData = {
|
|
43
|
-
...oldData
|
|
44
|
-
};
|
|
45
|
-
if (updatePath.length === 1) {
|
|
46
|
-
// @ts-expect-error NAS
|
|
47
|
-
newData[updatePath[0]] = value;
|
|
48
|
-
return newData;
|
|
49
|
-
}
|
|
50
|
-
const [head, ...tail] = updatePath;
|
|
51
|
-
// @ts-expect-error NAS
|
|
52
|
-
newData[head] = updateNestedDataByPath(newData[head], tail, value);
|
|
53
|
-
return newData;
|
|
54
|
-
}
|
|
55
|
-
return oldData;
|
|
56
|
-
};
|
|
1
|
+
"use strict";export const updateNestedDataByPath=(e,r,s)=>{if(r.length===0){return s}if(e instanceof Map){const n=new Map(e);if(r.length===1){n.set(r[0],s);return n}const[t,...i]=r;const c=n.get(t);n.set(t,updateNestedDataByPath(c??null,i,s));return n}if(e instanceof Set){const n=updateNestedDataByPath(Array.from(e),r,s);return new Set(Array.isArray(n)?n:[])}if(Array.isArray(e)){const n=[...e];if(r.length===1){n[r[0]]=s;return n}const[t,...i]=r;n[t]=updateNestedDataByPath(n[t],i,s);return n}if(e instanceof Object){const n={...e};if(r.length===1){n[r[0]]=s;return n}const[t,...i]=r;n[t]=updateNestedDataByPath(n[t],i,s);return n}return e};
|
|
@@ -1,231 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
4
|
-
import { ActivityIndicator, StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
|
5
|
-
import { ChevronDown, Check, night } from "@buoy-gg/shared-ui";
|
|
6
|
-
import { conditionsCanApply, getNetworkCondition, setNetworkCondition, subscribeNetworkConditions } from "./store";
|
|
7
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
-
const options = [{
|
|
9
|
-
profile: "normal",
|
|
10
|
-
label: "No throttling"
|
|
11
|
-
}, {
|
|
12
|
-
profile: "slow",
|
|
13
|
-
label: "Slow"
|
|
14
|
-
}, {
|
|
15
|
-
profile: "verySlow",
|
|
16
|
-
label: "Very slow"
|
|
17
|
-
}, {
|
|
18
|
-
profile: "offline",
|
|
19
|
-
label: "Offline"
|
|
20
|
-
}];
|
|
21
|
-
const summaries = {
|
|
22
|
-
normal: "No added delay",
|
|
23
|
-
slow: "+500 ms before each new request",
|
|
24
|
-
verySlow: "+2 seconds before each new request",
|
|
25
|
-
offline: "New requests fail before sending"
|
|
26
|
-
};
|
|
27
|
-
export function NetworkConditionsControl({
|
|
28
|
-
remote
|
|
29
|
-
}) {
|
|
30
|
-
const local = useSyncExternalStore(subscribeNetworkConditions, getNetworkCondition, getNetworkCondition);
|
|
31
|
-
const localAvailable = useSyncExternalStore(subscribeNetworkConditions, conditionsCanApply, conditionsCanApply);
|
|
32
|
-
const [expanded, setExpanded] = useState(false);
|
|
33
|
-
const [error, setError] = useState();
|
|
34
|
-
const [pending, setPending] = useState(false);
|
|
35
|
-
const busy = useRef(false);
|
|
36
|
-
const mounted = useRef(true);
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
mounted.current = true;
|
|
39
|
-
return () => {
|
|
40
|
-
mounted.current = false;
|
|
41
|
-
};
|
|
42
|
-
}, []);
|
|
43
|
-
const profile = remote ? remote.profile : local;
|
|
44
|
-
const available = remote ? remote.available : localAvailable;
|
|
45
|
-
const active = profile !== null && profile !== "normal";
|
|
46
|
-
const tint = profile === "offline" ? night.color.danger : active ? night.color.warning : night.color.accent;
|
|
47
|
-
async function select(value) {
|
|
48
|
-
if (!available || busy.current) return;
|
|
49
|
-
if (value === profile) {
|
|
50
|
-
setExpanded(false);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
busy.current = true;
|
|
54
|
-
setPending(true);
|
|
55
|
-
setError(undefined);
|
|
56
|
-
try {
|
|
57
|
-
if (remote) await remote.onChange(value);else setNetworkCondition(value);
|
|
58
|
-
if (mounted.current) setExpanded(false);
|
|
59
|
-
} catch (failure) {
|
|
60
|
-
if (mounted.current) setError(failure instanceof Error ? failure.message : String(failure));
|
|
61
|
-
} finally {
|
|
62
|
-
busy.current = false;
|
|
63
|
-
if (mounted.current) setPending(false);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const label = options.find(option => option.profile === profile)?.label ?? "Unavailable";
|
|
67
|
-
return /*#__PURE__*/_jsxs(View, {
|
|
68
|
-
style: styles.container,
|
|
69
|
-
testID: "buoy-network-throttling-screen",
|
|
70
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
71
|
-
style: styles.heading,
|
|
72
|
-
children: "Connection profile"
|
|
73
|
-
}), /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
74
|
-
testID: "buoy-network-conditions",
|
|
75
|
-
accessibilityRole: "button",
|
|
76
|
-
accessibilityLabel: `Network throttling: ${label}`,
|
|
77
|
-
accessibilityState: {
|
|
78
|
-
expanded,
|
|
79
|
-
disabled: !available || pending
|
|
80
|
-
},
|
|
81
|
-
disabled: !available || pending,
|
|
82
|
-
onPress: () => setExpanded(value => !value),
|
|
83
|
-
style: [styles.dropdown, expanded && styles.dropdownOpen, !available && styles.disabled],
|
|
84
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
85
|
-
style: [styles.value, active && {
|
|
86
|
-
color: tint
|
|
87
|
-
}],
|
|
88
|
-
children: label
|
|
89
|
-
}), pending ? /*#__PURE__*/_jsx(ActivityIndicator, {
|
|
90
|
-
size: "small",
|
|
91
|
-
color: night.color.textSecondary
|
|
92
|
-
}) : /*#__PURE__*/_jsx(ChevronDown, {
|
|
93
|
-
size: 16,
|
|
94
|
-
color: night.color.textSecondary
|
|
95
|
-
})]
|
|
96
|
-
}), expanded && /*#__PURE__*/_jsx(View, {
|
|
97
|
-
accessibilityRole: "radiogroup",
|
|
98
|
-
accessibilityLabel: "Connection profile",
|
|
99
|
-
style: styles.options,
|
|
100
|
-
children: options.map(option => {
|
|
101
|
-
const selected = profile === option.profile;
|
|
102
|
-
return /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
103
|
-
testID: `buoy-network-condition-${option.profile}`,
|
|
104
|
-
accessibilityRole: "radio",
|
|
105
|
-
accessibilityLabel: option.label,
|
|
106
|
-
accessibilityState: {
|
|
107
|
-
checked: selected,
|
|
108
|
-
disabled: !available || pending
|
|
109
|
-
},
|
|
110
|
-
disabled: !available || pending,
|
|
111
|
-
onPress: () => void select(option.profile),
|
|
112
|
-
style: [styles.option, selected && styles.selected],
|
|
113
|
-
children: [/*#__PURE__*/_jsxs(View, {
|
|
114
|
-
style: styles.optionBody,
|
|
115
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
116
|
-
style: [styles.optionTitle, selected && {
|
|
117
|
-
color: tint
|
|
118
|
-
}],
|
|
119
|
-
children: option.label
|
|
120
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
121
|
-
style: styles.caption,
|
|
122
|
-
children: summaries[option.profile]
|
|
123
|
-
})]
|
|
124
|
-
}), selected && /*#__PURE__*/_jsx(Check, {
|
|
125
|
-
size: 16,
|
|
126
|
-
color: tint
|
|
127
|
-
})]
|
|
128
|
-
}, option.profile);
|
|
129
|
-
})
|
|
130
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
131
|
-
style: styles.caption,
|
|
132
|
-
accessibilityLiveRegion: "polite",
|
|
133
|
-
children: pending ? "Applying to device…" : !available ? remote ? "Conditions unavailable on this device" : "Requires a signed-in account and a development build" : profile ? summaries[profile] : "Waiting for device status"
|
|
134
|
-
}), !!error && /*#__PURE__*/_jsx(Text, {
|
|
135
|
-
accessibilityRole: "alert",
|
|
136
|
-
style: styles.error,
|
|
137
|
-
children: error
|
|
138
|
-
}), /*#__PURE__*/_jsxs(View, {
|
|
139
|
-
style: styles.help,
|
|
140
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
141
|
-
style: styles.heading,
|
|
142
|
-
children: "How it works"
|
|
143
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
144
|
-
style: styles.caption,
|
|
145
|
-
children: "Affects new HTTP requests through global fetch and XHR. Slow adds a wait before sending; download speed stays unchanged."
|
|
146
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
147
|
-
style: styles.caption,
|
|
148
|
-
children: "Stays active when you close this tool or pause capture. Choose No throttling to stop. Reloading the app resets it."
|
|
149
|
-
})]
|
|
150
|
-
})]
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
const styles = StyleSheet.create({
|
|
154
|
-
container: {
|
|
155
|
-
padding: night.gutter,
|
|
156
|
-
gap: 10
|
|
157
|
-
},
|
|
158
|
-
heading: {
|
|
159
|
-
fontSize: night.font.caption,
|
|
160
|
-
fontWeight: "600",
|
|
161
|
-
color: night.color.textSecondary
|
|
162
|
-
},
|
|
163
|
-
dropdown: {
|
|
164
|
-
flexDirection: "row",
|
|
165
|
-
alignItems: "center",
|
|
166
|
-
justifyContent: "space-between",
|
|
167
|
-
gap: 12,
|
|
168
|
-
minHeight: 44,
|
|
169
|
-
paddingHorizontal: 12,
|
|
170
|
-
paddingVertical: 10,
|
|
171
|
-
borderRadius: night.radius.segment,
|
|
172
|
-
borderWidth: 1,
|
|
173
|
-
borderColor: night.color.separator,
|
|
174
|
-
backgroundColor: night.color.surfaceElevated
|
|
175
|
-
},
|
|
176
|
-
dropdownOpen: {
|
|
177
|
-
borderColor: night.color.accentBorderStrong
|
|
178
|
-
},
|
|
179
|
-
value: {
|
|
180
|
-
flex: 1,
|
|
181
|
-
fontSize: night.font.body,
|
|
182
|
-
color: night.color.text
|
|
183
|
-
},
|
|
184
|
-
options: {
|
|
185
|
-
padding: 4,
|
|
186
|
-
borderRadius: night.radius.row,
|
|
187
|
-
borderWidth: 1,
|
|
188
|
-
borderColor: night.color.border,
|
|
189
|
-
backgroundColor: night.color.surface
|
|
190
|
-
},
|
|
191
|
-
option: {
|
|
192
|
-
flexDirection: "row",
|
|
193
|
-
alignItems: "center",
|
|
194
|
-
gap: 12,
|
|
195
|
-
minHeight: 54,
|
|
196
|
-
padding: 10,
|
|
197
|
-
borderRadius: night.radius.segment
|
|
198
|
-
},
|
|
199
|
-
optionBody: {
|
|
200
|
-
flex: 1,
|
|
201
|
-
gap: 4
|
|
202
|
-
},
|
|
203
|
-
optionTitle: {
|
|
204
|
-
fontSize: night.font.caption,
|
|
205
|
-
fontWeight: "600",
|
|
206
|
-
color: night.color.text
|
|
207
|
-
},
|
|
208
|
-
selected: {
|
|
209
|
-
backgroundColor: night.color.surfaceElevated
|
|
210
|
-
},
|
|
211
|
-
disabled: {
|
|
212
|
-
opacity: 0.45
|
|
213
|
-
},
|
|
214
|
-
caption: {
|
|
215
|
-
fontSize: night.font.caption,
|
|
216
|
-
lineHeight: 19,
|
|
217
|
-
color: night.color.textSecondary
|
|
218
|
-
},
|
|
219
|
-
help: {
|
|
220
|
-
marginTop: 14,
|
|
221
|
-
paddingTop: 16,
|
|
222
|
-
gap: 10,
|
|
223
|
-
borderTopWidth: 1,
|
|
224
|
-
borderTopColor: night.color.separator
|
|
225
|
-
},
|
|
226
|
-
error: {
|
|
227
|
-
fontSize: night.font.caption,
|
|
228
|
-
lineHeight: 18,
|
|
229
|
-
color: night.color.danger
|
|
230
|
-
}
|
|
231
|
-
});
|
|
1
|
+
"use strict";import{useEffect as j,useRef as x,useState as h,useSyncExternalStore as k}from"react";import{ActivityIndicator as q,StyleSheet as A,Text as i,TouchableOpacity as R,View as p}from"react-native";import{ChevronDown as L,Check as O,night as e}from"@buoy-gg/shared-ui";import{conditionsCanApply as T,getNetworkCondition as z,setNetworkCondition as P,subscribeNetworkConditions as N}from"./store";import{jsx as r,jsxs as f}from"react/jsx-runtime";const H=[{profile:"normal",label:"No throttling"},{profile:"slow",label:"Slow"},{profile:"verySlow",label:"Very slow"},{profile:"offline",label:"Offline"}];const E={normal:"No added delay",slow:"+500 ms before each new request",verySlow:"+2 seconds before each new request",offline:"New requests fail before sending"};export function NetworkConditionsControl({remote:s}){const D=k(N,z,z);const I=k(N,T,T);const[u,b]=h(false);const[w,S]=h();const[c,m]=h(false);const g=x(false);const d=x(true);j(()=>{d.current=true;return()=>{d.current=false}},[]);const n=s?s.profile:D;const a=s?s.available:I;const C=n!==null&&n!=="normal";const y=n==="offline"?e.color.danger:C?e.color.warning:e.color.accent;async function W(t){if(!a||g.current)return;if(t===n){b(false);return}g.current=true;m(true);S(void 0);try{if(s)await s.onChange(t);else P(t);if(d.current)b(false)}catch(l){if(d.current)S(l instanceof Error?l.message:String(l))}finally{g.current=false;if(d.current)m(false)}}const v=H.find(t=>t.profile===n)?.label??"Unavailable";return f(p,{style:o.container,testID:"buoy-network-throttling-screen",children:[r(i,{style:o.heading,children:"Connection profile"}),f(R,{testID:"buoy-network-conditions",accessibilityRole:"button",accessibilityLabel:`Network throttling: ${v}`,accessibilityState:{expanded:u,disabled:!a||c},disabled:!a||c,onPress:()=>b(t=>!t),style:[o.dropdown,u&&o.dropdownOpen,!a&&o.disabled],children:[r(i,{style:[o.value,C&&{color:y}],children:v}),c?r(q,{size:"small",color:e.color.textSecondary}):r(L,{size:16,color:e.color.textSecondary})]}),u&&r(p,{accessibilityRole:"radiogroup",accessibilityLabel:"Connection profile",style:o.options,children:H.map(t=>{const l=n===t.profile;return f(R,{testID:`buoy-network-condition-${t.profile}`,accessibilityRole:"radio",accessibilityLabel:t.label,accessibilityState:{checked:l,disabled:!a||c},disabled:!a||c,onPress:()=>void W(t.profile),style:[o.option,l&&o.selected],children:[f(p,{style:o.optionBody,children:[r(i,{style:[o.optionTitle,l&&{color:y}],children:t.label}),r(i,{style:o.caption,children:E[t.profile]})]}),l&&r(O,{size:16,color:y})]},t.profile)})}),r(i,{style:o.caption,accessibilityLiveRegion:"polite",children:c?"Applying to device\u2026":!a?s?"Conditions unavailable on this device":"Requires a signed-in account and a development build":n?E[n]:"Waiting for device status"}),!!w&&r(i,{accessibilityRole:"alert",style:o.error,children:w}),f(p,{style:o.help,children:[r(i,{style:o.heading,children:"How it works"}),r(i,{style:o.caption,children:"Affects new HTTP requests through global fetch and XHR. Slow adds a wait before sending; download speed stays unchanged."}),r(i,{style:o.caption,children:"Stays active when you close this tool or pause capture. Choose No throttling to stop. Reloading the app resets it."})]})]})}const o=A.create({container:{padding:e.gutter,gap:10},heading:{fontSize:e.font.caption,fontWeight:"600",color:e.color.textSecondary},dropdown:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:44,paddingHorizontal:12,paddingVertical:10,borderRadius:e.radius.segment,borderWidth:1,borderColor:e.color.separator,backgroundColor:e.color.surfaceElevated},dropdownOpen:{borderColor:e.color.accentBorderStrong},value:{flex:1,fontSize:e.font.body,color:e.color.text},options:{padding:4,borderRadius:e.radius.row,borderWidth:1,borderColor:e.color.border,backgroundColor:e.color.surface},option:{flexDirection:"row",alignItems:"center",gap:12,minHeight:54,padding:10,borderRadius:e.radius.segment},optionBody:{flex:1,gap:4},optionTitle:{fontSize:e.font.caption,fontWeight:"600",color:e.color.text},selected:{backgroundColor:e.color.surfaceElevated},disabled:{opacity:.45},caption:{fontSize:e.font.caption,lineHeight:19,color:e.color.textSecondary},help:{marginTop:14,paddingTop:16,gap:10,borderTopWidth:1,borderTopColor:e.color.separator},error:{fontSize:e.font.caption,lineHeight:18,color:e.color.danger}});
|
|
@@ -1,135 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
// @vitest-environment jsdom
|
|
4
|
-
import { act, createElement } from "react";
|
|
5
|
-
import { createRoot } from "react-dom/client";
|
|
6
|
-
import { afterEach, beforeEach, expect, it, vi } from "vitest";
|
|
7
|
-
import { NetworkConditionsControl } from "./NetworkConditionsControl";
|
|
8
|
-
vi.mock("@buoy-gg/shared-ui", async () => ({
|
|
9
|
-
ChevronDown: () => null,
|
|
10
|
-
Check: () => null,
|
|
11
|
-
night: (await vi.importActual("../../../../shared/src/ui/night/nightTheme")).night
|
|
12
|
-
}));
|
|
13
|
-
vi.mock("react-native", () => ({
|
|
14
|
-
StyleSheet: {
|
|
15
|
-
create: value => value
|
|
16
|
-
},
|
|
17
|
-
View: ({
|
|
18
|
-
children
|
|
19
|
-
}) => /*#__PURE__*/createElement("div", null, children),
|
|
20
|
-
Text: ({
|
|
21
|
-
children
|
|
22
|
-
}) => /*#__PURE__*/createElement("span", null, children),
|
|
23
|
-
ActivityIndicator: () => /*#__PURE__*/createElement("span", null, "pending"),
|
|
24
|
-
TouchableOpacity: ({
|
|
25
|
-
children,
|
|
26
|
-
onPress,
|
|
27
|
-
disabled,
|
|
28
|
-
accessibilityLabel,
|
|
29
|
-
accessibilityState,
|
|
30
|
-
testID
|
|
31
|
-
}) => /*#__PURE__*/createElement("button", {
|
|
32
|
-
onClick: onPress,
|
|
33
|
-
disabled,
|
|
34
|
-
"aria-label": accessibilityLabel,
|
|
35
|
-
"aria-checked": accessibilityState?.checked,
|
|
36
|
-
"data-testid": testID
|
|
37
|
-
}, children)
|
|
38
|
-
}));
|
|
39
|
-
vi.mock("./store", () => ({
|
|
40
|
-
NETWORK_CONDITIONS: {
|
|
41
|
-
normal: {
|
|
42
|
-
label: "Normal"
|
|
43
|
-
},
|
|
44
|
-
slow: {
|
|
45
|
-
label: "Slow"
|
|
46
|
-
},
|
|
47
|
-
verySlow: {
|
|
48
|
-
label: "Very slow"
|
|
49
|
-
},
|
|
50
|
-
offline: {
|
|
51
|
-
label: "Offline"
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
getNetworkCondition: () => "normal",
|
|
55
|
-
conditionsCanApply: () => true,
|
|
56
|
-
subscribeNetworkConditions: () => () => {},
|
|
57
|
-
setNetworkCondition: vi.fn()
|
|
58
|
-
}));
|
|
59
|
-
let root;
|
|
60
|
-
let container;
|
|
61
|
-
beforeEach(() => {
|
|
62
|
-
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|
|
63
|
-
container = document.createElement("div");
|
|
64
|
-
root = createRoot(container);
|
|
65
|
-
});
|
|
66
|
-
afterEach(() => act(() => root.unmount()));
|
|
67
|
-
const button = profile => container.querySelector(`[data-testid="buoy-network-condition-${profile}"]`);
|
|
68
|
-
function render(remote) {
|
|
69
|
-
act(() => root.render(/*#__PURE__*/createElement(NetworkConditionsControl, {
|
|
70
|
-
remote
|
|
71
|
-
})));
|
|
72
|
-
}
|
|
73
|
-
const dropdown = () => container.querySelector('[data-testid="buoy-network-conditions"]');
|
|
74
|
-
const open = () => act(() => dropdown().click());
|
|
75
|
-
it("defaults to a closed No throttling dropdown and closes when the current option is chosen", () => {
|
|
76
|
-
const onChange = vi.fn();
|
|
77
|
-
render({
|
|
78
|
-
profile: "normal",
|
|
79
|
-
available: true,
|
|
80
|
-
onChange
|
|
81
|
-
});
|
|
82
|
-
expect(dropdown().textContent).toBe("No throttling");
|
|
83
|
-
expect(button("normal")).toBeNull();
|
|
84
|
-
open();
|
|
85
|
-
expect(["normal", "slow", "verySlow", "offline"].every(value => !!button(value))).toBe(true);
|
|
86
|
-
act(() => button("normal").click());
|
|
87
|
-
expect(button("normal")).toBeNull();
|
|
88
|
-
expect(onChange).not.toHaveBeenCalled();
|
|
89
|
-
});
|
|
90
|
-
it("blocks duplicate remote changes and waits for the device profile before selecting it", async () => {
|
|
91
|
-
let finish;
|
|
92
|
-
const onChange = vi.fn(() => new Promise(resolve => {
|
|
93
|
-
finish = resolve;
|
|
94
|
-
}));
|
|
95
|
-
render({
|
|
96
|
-
profile: "normal",
|
|
97
|
-
available: true,
|
|
98
|
-
onChange
|
|
99
|
-
});
|
|
100
|
-
open();
|
|
101
|
-
act(() => button("slow").click());
|
|
102
|
-
expect(button("offline").disabled).toBe(true);
|
|
103
|
-
expect(button("normal").getAttribute("aria-checked")).toBe("true");
|
|
104
|
-
act(() => button("offline").click());
|
|
105
|
-
expect(onChange).toHaveBeenCalledExactlyOnceWith("slow");
|
|
106
|
-
await act(async () => finish());
|
|
107
|
-
render({
|
|
108
|
-
profile: "slow",
|
|
109
|
-
available: true,
|
|
110
|
-
onChange
|
|
111
|
-
});
|
|
112
|
-
expect(dropdown().textContent).toBe("Slow");
|
|
113
|
-
expect(button("slow")).toBeNull();
|
|
114
|
-
open();
|
|
115
|
-
expect(button("slow").getAttribute("aria-checked")).toBe("true");
|
|
116
|
-
});
|
|
117
|
-
it("reports a remote error, permits retry, and disables unavailable devices", async () => {
|
|
118
|
-
const onChange = vi.fn().mockRejectedValue(new Error("Device disconnected"));
|
|
119
|
-
render({
|
|
120
|
-
profile: "normal",
|
|
121
|
-
available: true,
|
|
122
|
-
onChange
|
|
123
|
-
});
|
|
124
|
-
open();
|
|
125
|
-
await act(async () => button("offline").click());
|
|
126
|
-
expect(container.textContent).toContain("Device disconnected");
|
|
127
|
-
expect(button("offline").disabled).toBe(false);
|
|
128
|
-
render({
|
|
129
|
-
profile: null,
|
|
130
|
-
available: false,
|
|
131
|
-
onChange
|
|
132
|
-
});
|
|
133
|
-
expect(button("normal").disabled).toBe(true);
|
|
134
|
-
expect(container.textContent).toContain("Conditions unavailable on this device");
|
|
135
|
-
});
|
|
1
|
+
"use strict";import{act as n,createElement as r}from"react";import{createRoot as p}from"react-dom/client";import{afterEach as C,beforeEach as v,expect as t,it as u,vi as l}from"vitest";import{NetworkConditionsControl as k}from"./NetworkConditionsControl";l.mock("@buoy-gg/shared-ui",async()=>({ChevronDown:()=>null,Check:()=>null,night:(await l.importActual("../../../../shared/src/ui/night/nightTheme")).night}));l.mock("react-native",()=>({StyleSheet:{create:e=>e},View:({children:e})=>r("div",null,e),Text:({children:e})=>r("span",null,e),ActivityIndicator:()=>r("span",null,"pending"),TouchableOpacity:({children:e,onPress:a,disabled:d,accessibilityLabel:h,accessibilityState:b,testID:w})=>r("button",{onClick:a,disabled:d,"aria-label":h,"aria-checked":b?.checked,"data-testid":w},e)}));l.mock("./store",()=>({NETWORK_CONDITIONS:{normal:{label:"Normal"},slow:{label:"Slow"},verySlow:{label:"Very slow"},offline:{label:"Offline"}},getNetworkCondition:()=>"normal",conditionsCanApply:()=>true,subscribeNetworkConditions:()=>()=>{},setNetworkCondition:l.fn()}));let f;let i;v(()=>{globalThis.IS_REACT_ACT_ENVIRONMENT=true;i=document.createElement("div");f=p(i)});C(()=>n(()=>f.unmount()));const o=e=>i.querySelector(`[data-testid="buoy-network-condition-${e}"]`);function c(e){n(()=>f.render(r(k,{remote:e})))}const m=()=>i.querySelector('[data-testid="buoy-network-conditions"]');const s=()=>n(()=>m().click());u("defaults to a closed No throttling dropdown and closes when the current option is chosen",()=>{const e=l.fn();c({profile:"normal",available:true,onChange:e});t(m().textContent).toBe("No throttling");t(o("normal")).toBeNull();s();t(["normal","slow","verySlow","offline"].every(a=>!!o(a))).toBe(true);n(()=>o("normal").click());t(o("normal")).toBeNull();t(e).not.toHaveBeenCalled()});u("blocks duplicate remote changes and waits for the device profile before selecting it",async()=>{let e;const a=l.fn(()=>new Promise(d=>{e=d}));c({profile:"normal",available:true,onChange:a});s();n(()=>o("slow").click());t(o("offline").disabled).toBe(true);t(o("normal").getAttribute("aria-checked")).toBe("true");n(()=>o("offline").click());t(a).toHaveBeenCalledExactlyOnceWith("slow");await n(async()=>e());c({profile:"slow",available:true,onChange:a});t(m().textContent).toBe("Slow");t(o("slow")).toBeNull();s();t(o("slow").getAttribute("aria-checked")).toBe("true")});u("reports a remote error, permits retry, and disables unavailable devices",async()=>{const e=l.fn().mockRejectedValue(new Error("Device disconnected"));c({profile:"normal",available:true,onChange:e});s();await n(async()=>o("offline").click());t(i.textContent).toContain("Device disconnected");t(o("offline").disabled).toBe(false);c({profile:null,available:false,onChange:e});t(o("normal").disabled).toBe(true);t(i.textContent).toContain("Conditions unavailable on this device")});
|
|
@@ -1,29 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { useSyncExternalStore } from "react";
|
|
4
|
-
import { Text, View } from "react-native";
|
|
5
|
-
import { NetworkIcon } from "@buoy-gg/shared-ui";
|
|
6
|
-
import { getNetworkCondition, subscribeNetworkConditions, NETWORK_CONDITIONS } from "./store";
|
|
7
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
-
export function NetworkConditionsIcon({
|
|
9
|
-
size
|
|
10
|
-
}) {
|
|
11
|
-
const profile = useSyncExternalStore(subscribeNetworkConditions, getNetworkCondition, getNetworkCondition);
|
|
12
|
-
return /*#__PURE__*/_jsxs(View, {
|
|
13
|
-
accessibilityLabel: profile === "normal" ? "Network" : `Network: ${NETWORK_CONDITIONS[profile].label}`,
|
|
14
|
-
children: [/*#__PURE__*/_jsx(NetworkIcon, {
|
|
15
|
-
size: size
|
|
16
|
-
}), profile !== "normal" && /*#__PURE__*/_jsx(Text, {
|
|
17
|
-
testID: "buoy-network-condition-indicator",
|
|
18
|
-
style: {
|
|
19
|
-
position: "absolute",
|
|
20
|
-
top: -6,
|
|
21
|
-
right: -8,
|
|
22
|
-
color: "#FFCC66",
|
|
23
|
-
fontSize: 10,
|
|
24
|
-
fontWeight: "700"
|
|
25
|
-
},
|
|
26
|
-
children: profile === "offline" ? "OFF" : `+${NETWORK_CONDITIONS[profile].delayMs}`
|
|
27
|
-
})]
|
|
28
|
-
});
|
|
29
|
-
}
|
|
1
|
+
"use strict";import{useSyncExternalStore as n}from"react";import{Text as s,View as l}from"react-native";import{NetworkIcon as c}from"@buoy-gg/shared-ui";import{getNetworkCondition as t,subscribeNetworkConditions as m,NETWORK_CONDITIONS as i}from"./store";import{jsx as r,jsxs as a}from"react/jsx-runtime";export function NetworkConditionsIcon({size:e}){const o=n(m,t,t);return a(l,{accessibilityLabel:o==="normal"?"Network":`Network: ${i[o].label}`,children:[r(c,{size:e}),o!=="normal"&&r(s,{testID:"buoy-network-condition-indicator",style:{position:"absolute",top:-6,right:-8,color:"#FFCC66",fontSize:10,fontWeight:"700"},children:o==="offline"?"OFF":`+${i[o].delayMs}`})]})}
|