# WebStorageService

- File ID: file:15km3l4:webstorageservice-cs
- Path: NexusReader.UI.Shared/Services/WebStorageService.cs
- Role: service
- Layer: frontend

## Purpose

Provides a web-local-storage backed implementation of INativeStorageService for Blazor/JS runtime using IJSRuntime to persist and read simple string/bool values with Result wrapping and basic error handling.

## Key Details

Implements INativeStorageService for web Blazor clients via IJSRuntime localStorage calls; secure-named methods currently just delegate to plain methods (no added encryption).

## Symbols

- WebStorageService: Provides a web-local-storage backed implementation of INativeStorageService for Blazor/JS runtime using IJSRuntime to persist and read simple string/bool values with Result wrapping and basic error handling.
- SaveStringAsync(): Saves a string value into browser localStorage under the given key and returns a Result indicating success or failure.
- GetStringAsync(): Reads a string value from browser localStorage for the given key and returns it wrapped in a Result; failures produce a failed Result.
- SaveBoolAsync(): Convenience wrapper that saves a boolean by converting it to string and delegating to SaveStringAsync.
- GetBoolAsync(): Reads a stored string for the key, attempts to parse it as bool, and returns the parsed value or a default wrapped in a Result; catches errors and returns the default.
- RemoveAsync(): Removes an item from browser localStorage by key and returns Result success/failure.
- SaveSecureString(): Secure-named wrapper that currently delegates to SaveStringAsync (no extra security applied).
- GetSecureString(): Secure-named wrapper that delegates to GetStringAsync (no extra security applied).
- RemoveSecureAsync(): Secure-named wrapper that delegates to RemoveAsync (no extra security applied).

## Dependencies

- No resolved dependencies.

## Calls

- No resolved calls.

## Unresolved References

- dependency-target: NexusReader.Application.Abstractions.Services (INativeStorageService)
- dependency-target: Microsoft.JSInterop (IJSRuntime)
- dependency-target: FluentResults (Result)
- call-target: self
- call-target: self
- call-target: self
- call-target: self
- interaction-target: _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, value)
- interaction-target: _jsRuntime.InvokeAsync<string?>("localStorage.getItem", key)
- interaction-target: _jsRuntime.InvokeAsync<string?>("localStorage.getItem", key)
- interaction-target: _jsRuntime.InvokeVoidAsync("localStorage.removeItem", key)

## Coverage

- Symbols: 9
- Executable symbols: 8
- Executable symbols with control flow: 8
- Grounded edges: 9
- Unresolved references: 11
- Control-flow fragments: 8
- Unresolved jumps: 0
- Unsupported constructs: 0
- Control-flow coverage: 100%
- Required diagrams: 2
- Generated diagrams: 6

## Control Flow Fragments

- SaveStringAsync: 10 nodes, 9 edges, 0 jumps, 0 unsupported constructs
- GetStringAsync: 10 nodes, 9 edges, 0 jumps, 0 unsupported constructs
- SaveBoolAsync: 4 nodes, 3 edges, 1 jumps, 0 unsupported constructs
- GetBoolAsync: 20 nodes, 22 edges, 0 jumps, 0 unsupported constructs
- RemoveAsync: 10 nodes, 9 edges, 0 jumps, 0 unsupported constructs
- SaveSecureString: 5 nodes, 4 edges, 1 jumps, 0 unsupported constructs
- GetSecureString: 5 nodes, 4 edges, 1 jumps, 0 unsupported constructs
- RemoveSecureAsync: 4 nodes, 3 edges, 1 jumps, 0 unsupported constructs

## Diagrams

### WebStorageService Neighborhood

```mermaid
flowchart LR
    class_1uirugg_webstorageservice("WebStorageService")
    file_15km3l4_webstorageservice_cs("WebStorageService")
    method_16m1d8f_savestringasync[["SaveStringAsync()"]]
    method_17924up_removeasync[["RemoveAsync()"]]
    method_1bx0ikl_removesecureasync[["RemoveSecureAsync()"]]
    method_1rgphlw_getstringasync[["GetStringAsync()"]]
    method_1xwytsy_getsecurestring[["GetSecureString()"]]
    method_en9pi8_getboolasync[["GetBoolAsync()"]]
    method_hj2kxb_saveboolasync[["SaveBoolAsync()"]]
    method_ly29k7_savesecurestring[["SaveSecureString()"]]
```

### WebStorageService Execution Overview

```mermaid
flowchart TD
    class_1uirugg_webstorageservice("WebStorageService")
    method_16m1d8f_savestringasync[["SaveStringAsync()"]]
    method_17924up_removeasync[["RemoveAsync()"]]
    method_1bx0ikl_removesecureasync[["RemoveSecureAsync()"]]
    method_1rgphlw_getstringasync[["GetStringAsync()"]]
    method_1xwytsy_getsecurestring[["GetSecureString()"]]
    method_en9pi8_getboolasync[["GetBoolAsync()"]]
    method_hj2kxb_saveboolasync[["SaveBoolAsync()"]]
    method_ly29k7_savesecurestring[["SaveSecureString()"]]
    unresolved_unresolved_115hkr2_interaction_target{"Unresolved: _jsRuntime.InvokeVoidAsync(\\"localStorage.removeItem\\", key)"}
    unresolved_unresolved_1m7ni06_call_target{"Unresolved: GetStringAsync"}
    unresolved_unresolved_1oqkmck_interaction_target{"Unresolved: _jsRuntime.InvokeAsync<string?>(\\"localStorage.getItem\\", key)"}
    unresolved_unresolved_1yjg6nw_call_target{"Unresolved: RemoveAsync"}
    unresolved_unresolved_goqrxi_call_target{"Unresolved: SaveStringAsync"}
    unresolved_unresolved_h6kn8d_call_target{"Unresolved: SaveStringAsync"}
    unresolved_unresolved_zqfpll_interaction_target{"Unresolved: _jsRuntime.InvokeVoidAsync(\\"localStorage.setItem\\", key, value)"}
    class_1uirugg_webstorageservice -->|contains| method_16m1d8f_savestringasync
    class_1uirugg_webstorageservice -->|contains| method_17924up_removeasync
    class_1uirugg_webstorageservice -->|contains| method_1bx0ikl_removesecureasync
    class_1uirugg_webstorageservice -->|contains| method_1rgphlw_getstringasync
    class_1uirugg_webstorageservice -->|contains| method_1xwytsy_getsecurestring
    class_1uirugg_webstorageservice -->|contains| method_en9pi8_getboolasync
    class_1uirugg_webstorageservice -->|contains| method_hj2kxb_saveboolasync
    class_1uirugg_webstorageservice -->|contains| method_ly29k7_savesecurestring
    class_1uirugg_webstorageservice -->|unresolved interaction| unresolved_unresolved_115hkr2_interaction_target
    class_1uirugg_webstorageservice -->|unresolved interaction| unresolved_unresolved_1oqkmck_interaction_target
    class_1uirugg_webstorageservice -->|unresolved interaction| unresolved_unresolved_1oqkmck_interaction_target
    class_1uirugg_webstorageservice -->|unresolved interaction| unresolved_unresolved_zqfpll_interaction_target
    method_1bx0ikl_removesecureasync -->|unresolved call| unresolved_unresolved_1yjg6nw_call_target
    method_1xwytsy_getsecurestring -->|unresolved call| unresolved_unresolved_1m7ni06_call_target
    method_hj2kxb_saveboolasync -->|unresolved call| unresolved_unresolved_goqrxi_call_target
    method_ly29k7_savesecurestring -->|unresolved call| unresolved_unresolved_h6kn8d_call_target
```

### SaveStringAsync() Control Flow

```mermaid
flowchart TD
    method_16m1d8f_savestringasync__action_18_savestringasync_try_18_0__try("Begins protected execution")
    method_16m1d8f_savestringasync__action_18_try_catch_18__linear("Wraps JS call with exception handling")
    method_16m1d8f_savestringasync__action_20_savestringasync_await_20_1__await[["Waits for async work"]]
    method_16m1d8f_savestringasync__action_23_savestringasync_catch_23_3__catch("catch Exception ex")
    method_16m1d8f_savestringasync__entry(["SaveStringAsync entry"])
    method_16m1d8f_savestringasync__action_20_external_call_20__linear("Invoke JS localStorage.setItem")
    method_16m1d8f_savestringasync__action_21_return_21__return(["success"])
    method_16m1d8f_savestringasync__action_21_savestringasync_return_21_2__return(["Returns result"])
    method_16m1d8f_savestringasync__action_25_return_25__return(["failure"])
    method_16m1d8f_savestringasync__action_25_savestringasync_return_25_4__return(["Returns result"])
    method_16m1d8f_savestringasync__action_18_savestringasync_try_18_0__try -->|next| method_16m1d8f_savestringasync__action_20_savestringasync_await_20_1__await
    method_16m1d8f_savestringasync__action_18_try_catch_18__linear -->|next| method_16m1d8f_savestringasync__action_18_savestringasync_try_18_0__try
    method_16m1d8f_savestringasync__action_20_external_call_20__linear -->|return| method_16m1d8f_savestringasync__action_21_return_21__return
    method_16m1d8f_savestringasync__action_20_savestringasync_await_20_1__await -->|next| method_16m1d8f_savestringasync__action_20_external_call_20__linear
    method_16m1d8f_savestringasync__action_21_return_21__return -->|return| method_16m1d8f_savestringasync__action_21_savestringasync_return_21_2__return
    method_16m1d8f_savestringasync__action_21_savestringasync_return_21_2__return -->|exception| method_16m1d8f_savestringasync__action_23_savestringasync_catch_23_3__catch
    method_16m1d8f_savestringasync__action_23_savestringasync_catch_23_3__catch -->|return| method_16m1d8f_savestringasync__action_25_savestringasync_return_25_4__return
    method_16m1d8f_savestringasync__action_25_savestringasync_return_25_4__return -->|return| method_16m1d8f_savestringasync__action_25_return_25__return
    method_16m1d8f_savestringasync__entry -->|next| method_16m1d8f_savestringasync__action_18_try_catch_18__linear
```

### GetStringAsync() Control Flow

```mermaid
flowchart TD
    method_1rgphlw_getstringasync__action_31_getstringasync_try_31_0__try("Begins protected execution")
    method_1rgphlw_getstringasync__action_31_try_catch_31__linear("Wraps JS call with exception handling")
    method_1rgphlw_getstringasync__action_33_getstringasync_await_33_1__await[["Waits for async work"]]
    method_1rgphlw_getstringasync__action_36_getstringasync_catch_36_3__catch("catch Exception ex")
    method_1rgphlw_getstringasync__entry(["GetStringAsync entry"])
    method_1rgphlw_getstringasync__action_33_external_call_33__linear("Invoke JS localStorage.getItem")
    method_1rgphlw_getstringasync__action_34_getstringasync_return_34_2__return(["Returns result"])
    method_1rgphlw_getstringasync__action_34_return_34__return(["success"])
    method_1rgphlw_getstringasync__action_38_getstringasync_return_38_4__return(["Returns result"])
    method_1rgphlw_getstringasync__action_38_return_38__return(["failure"])
    method_1rgphlw_getstringasync__action_31_getstringasync_try_31_0__try -->|next| method_1rgphlw_getstringasync__action_33_getstringasync_await_33_1__await
    method_1rgphlw_getstringasync__action_31_try_catch_31__linear -->|next| method_1rgphlw_getstringasync__action_31_getstringasync_try_31_0__try
    method_1rgphlw_getstringasync__action_33_external_call_33__linear -->|return| method_1rgphlw_getstringasync__action_34_return_34__return
    method_1rgphlw_getstringasync__action_33_getstringasync_await_33_1__await -->|next| method_1rgphlw_getstringasync__action_33_external_call_33__linear
    method_1rgphlw_getstringasync__action_34_getstringasync_return_34_2__return -->|exception| method_1rgphlw_getstringasync__action_36_getstringasync_catch_36_3__catch
    method_1rgphlw_getstringasync__action_34_return_34__return -->|return| method_1rgphlw_getstringasync__action_34_getstringasync_return_34_2__return
    method_1rgphlw_getstringasync__action_36_getstringasync_catch_36_3__catch -->|return| method_1rgphlw_getstringasync__action_38_getstringasync_return_38_4__return
    method_1rgphlw_getstringasync__action_38_getstringasync_return_38_4__return -->|return| method_1rgphlw_getstringasync__action_38_return_38__return
    method_1rgphlw_getstringasync__entry -->|next| method_1rgphlw_getstringasync__action_31_try_catch_31__linear
```

### GetBoolAsync() Control Flow

_Warnings: diagram method_en9pi8_getboolasync__fragment_diagram exceeds preferred complexity thresholds (20 nodes, 22 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    method_en9pi8_getboolasync__action_46_getboolasync_try_46_0__try("Begins protected execution")
    method_en9pi8_getboolasync__action_48_getboolasync_await_48_1__await[["Waits for async work"]]
    method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__condition{"string.IsNullOrEmpty(value)) return Result.Ok(defaultValue"}
    method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__false("continue")
    method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__merge("merge")
    method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__true("exit")
    method_en9pi8_getboolasync__action_49_guard_clause_49__condition{"string.IsNullOrEmpty(value)"}
    method_en9pi8_getboolasync__action_49_guard_clause_49__false("continue")
    method_en9pi8_getboolasync__action_49_guard_clause_49__merge("merge")
    method_en9pi8_getboolasync__action_49_guard_clause_49__true("return default")
    method_en9pi8_getboolasync__action_50_branch_50__condition{"bool.TryParse(value, out result)"}
    method_en9pi8_getboolasync__action_50_branch_50__false("use default")
    method_en9pi8_getboolasync__action_50_branch_50__merge("merge")
    method_en9pi8_getboolasync__action_50_branch_50__true("parsed bool")
    method_en9pi8_getboolasync__action_52_getboolasync_catch_52_4__catch("Handles exception path")
    method_en9pi8_getboolasync__action_52_try_catch_52__linear("Returns default on any exception")
    method_en9pi8_getboolasync__entry(["GetBoolAsync entry"])
    method_en9pi8_getboolasync__action_48_external_call_48__linear("Invoke JS localStorage.getItem")
    method_en9pi8_getboolasync__action_50_getboolasync_return_50_3__return(["Returns result"])
    method_en9pi8_getboolasync__action_54_getboolasync_return_54_5__return(["Returns result"])
    method_en9pi8_getboolasync__action_46_getboolasync_try_46_0__try -->|next| method_en9pi8_getboolasync__action_48_getboolasync_await_48_1__await
    method_en9pi8_getboolasync__action_48_external_call_48__linear -->|next| method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__condition
    method_en9pi8_getboolasync__action_48_getboolasync_await_48_1__await -->|next| method_en9pi8_getboolasync__action_48_external_call_48__linear
    method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__condition -->|continue| method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__false
    method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__condition -->|exit| method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__true
    method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__false -->|next| method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__merge
    method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__merge -->|next| method_en9pi8_getboolasync__action_49_guard_clause_49__condition
    method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__true -->|next| method_en9pi8_getboolasync__action_49_getboolasync_guard_clause_49_2__merge
    method_en9pi8_getboolasync__action_49_guard_clause_49__condition -->|continue| method_en9pi8_getboolasync__action_49_guard_clause_49__false
    method_en9pi8_getboolasync__action_49_guard_clause_49__condition -->|return default| method_en9pi8_getboolasync__action_49_guard_clause_49__true
    method_en9pi8_getboolasync__action_49_guard_clause_49__false -->|next| method_en9pi8_getboolasync__action_49_guard_clause_49__merge
    method_en9pi8_getboolasync__action_49_guard_clause_49__merge -->|next| method_en9pi8_getboolasync__action_50_branch_50__condition
    method_en9pi8_getboolasync__action_49_guard_clause_49__true -->|next| method_en9pi8_getboolasync__action_49_guard_clause_49__merge
    method_en9pi8_getboolasync__action_50_branch_50__condition -->|use default| method_en9pi8_getboolasync__action_50_branch_50__false
    method_en9pi8_getboolasync__action_50_branch_50__condition -->|parsed bool| method_en9pi8_getboolasync__action_50_branch_50__true
    method_en9pi8_getboolasync__action_50_branch_50__false -->|next| method_en9pi8_getboolasync__action_50_branch_50__merge
    method_en9pi8_getboolasync__action_50_branch_50__merge -->|return| method_en9pi8_getboolasync__action_50_getboolasync_return_50_3__return
    method_en9pi8_getboolasync__action_50_branch_50__true -->|next| method_en9pi8_getboolasync__action_50_branch_50__merge
    method_en9pi8_getboolasync__action_50_getboolasync_return_50_3__return -->|next| method_en9pi8_getboolasync__action_52_try_catch_52__linear
    method_en9pi8_getboolasync__action_52_getboolasync_catch_52_4__catch -->|return| method_en9pi8_getboolasync__action_54_getboolasync_return_54_5__return
    method_en9pi8_getboolasync__action_52_try_catch_52__linear -->|exception| method_en9pi8_getboolasync__action_52_getboolasync_catch_52_4__catch
    method_en9pi8_getboolasync__entry -->|next| method_en9pi8_getboolasync__action_46_getboolasync_try_46_0__try
```

### RemoveAsync() Control Flow

```mermaid
flowchart TD
    method_17924up_removeasync__action_60_removeasync_try_60_0__try("Begins protected execution")
    method_17924up_removeasync__action_60_try_catch_60__linear("Wraps JS call with exception handling")
    method_17924up_removeasync__action_62_removeasync_await_62_1__await[["Waits for async work"]]
    method_17924up_removeasync__action_65_removeasync_catch_65_3__catch("catch Exception ex")
    method_17924up_removeasync__entry(["RemoveAsync entry"])
    method_17924up_removeasync__action_62_external_call_62__linear("Invoke JS localStorage.removeItem")
    method_17924up_removeasync__action_63_removeasync_return_63_2__return(["Returns result"])
    method_17924up_removeasync__action_63_return_63__return(["success"])
    method_17924up_removeasync__action_67_removeasync_return_67_4__return(["Returns result"])
    method_17924up_removeasync__action_67_return_67__return(["failure"])
    method_17924up_removeasync__action_60_removeasync_try_60_0__try -->|next| method_17924up_removeasync__action_62_removeasync_await_62_1__await
    method_17924up_removeasync__action_60_try_catch_60__linear -->|next| method_17924up_removeasync__action_60_removeasync_try_60_0__try
    method_17924up_removeasync__action_62_external_call_62__linear -->|return| method_17924up_removeasync__action_63_return_63__return
    method_17924up_removeasync__action_62_removeasync_await_62_1__await -->|next| method_17924up_removeasync__action_62_external_call_62__linear
    method_17924up_removeasync__action_63_removeasync_return_63_2__return -->|exception| method_17924up_removeasync__action_65_removeasync_catch_65_3__catch
    method_17924up_removeasync__action_63_return_63__return -->|return| method_17924up_removeasync__action_63_removeasync_return_63_2__return
    method_17924up_removeasync__action_65_removeasync_catch_65_3__catch -->|return| method_17924up_removeasync__action_67_removeasync_return_67_4__return
    method_17924up_removeasync__action_67_removeasync_return_67_4__return -->|return| method_17924up_removeasync__action_67_return_67__return
    method_17924up_removeasync__entry -->|next| method_17924up_removeasync__action_60_try_catch_60__linear
```

## Diagram Validation

- Status: warn
- Warning: control-flow: diagram method_en9pi8_getboolasync__fragment_diagram exceeds preferred complexity thresholds (20 nodes, 22 edges).
