browser/store.rs
1use gpui::{App, Task};
2use std::path::PathBuf;
3
4/// Where a page keeps its cookies, storage and cache.
5///
6/// The default is the platform's own store, shared by every page built with
7/// it.
8#[derive(Clone, Debug, Default, PartialEq, Eq)]
9pub struct DataStore {
10 pub(crate) incognito: bool,
11 pub(crate) directory: Option<PathBuf>,
12 pub(crate) identifier: Option<[u8; 16]>,
13}
14
15impl DataStore {
16 pub fn new() -> Self {
17 Self::default()
18 }
19
20 /// Kept in memory and gone with the page. Overrides the directory and
21 /// the identifier. On Windows, needs WebView2 Runtime 101.0.1210.39 or
22 /// later, and is ignored before it.
23 pub fn incognito(mut self) -> Self {
24 self.incognito = true;
25 self
26 }
27
28 /// Windows: the directory the store lives in. Pages built with
29 /// one directory share one store. Ignored on macOS.
30 pub fn with_directory(mut self, directory: impl Into<PathBuf>) -> Self {
31 self.directory = Some(directory.into());
32 self
33 }
34
35 /// macOS 14 and later: the persistent store with this identifier, a UUID's
36 /// bytes. Pages built with one identifier share one store. Ignored
37 /// elsewhere, and on earlier macOS, where the page uses the default store.
38 pub fn with_identifier(mut self, identifier: [u8; 16]) -> Self {
39 self.identifier = Some(identifier);
40 self
41 }
42
43 /// Clears the cookies, storage and cache this store keeps. Every page
44 /// built with the store must be closed first. Resolves to whether it was
45 /// cleared: an
46 /// incognito store keeps nothing and resolves `true`. Resolves `false` off
47 /// macOS.
48 ///
49 /// On macOS before 14 an identifier's store is the default one.
50 pub fn clear(&self, cx: &App) -> Task<bool> {
51 if self.incognito {
52 return Task::ready(true);
53 }
54 let (cleared, answer) = async_channel::bounded(1);
55 crate::page::clear_store(self, move |ok| {
56 let _ = cleared.try_send(ok);
57 });
58 cx.foreground_executor()
59 .spawn(async move { answer.recv().await.unwrap_or(false) })
60 }
61
62 /// What this store holds. Resolves `None` where the platform cannot tell:
63 /// off macOS. An incognito store holds nothing.
64 pub fn usage(&self, cx: &App) -> Task<Option<Usage>> {
65 if self.incognito {
66 return Task::ready(Some(Usage::default()));
67 }
68 let (reported, answer) = async_channel::bounded(1);
69 crate::page::store_usage(self, move |usage| {
70 let _ = reported.try_send(usage);
71 });
72 cx.foreground_executor()
73 .spawn(async move { answer.recv().await.ok().flatten() })
74 }
75}
76
77/// What a [`DataStore`] holds.
78#[derive(Clone, Debug, Default, PartialEq, Eq)]
79pub struct Usage {
80 /// The sites holding any data, by the name the platform shows for each.
81 pub sites: Vec<String>,
82}