Skip to main content

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}