We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: StorageObject doesn't return < 0 when using expiry
### Description

When the stored value is expired, the returned interval is set to 86400 and will therefore not expire. 

### URL to code causing the issue

https://github.com/litestar-org/litestar/blob/main/litestar/stores/base.py#L122

### MCVE

```python
from pathlib import Path
from litestar.stores.file import FileStore

store = FileStore(path=Path("test.db"))

async def setstore() -> None:
  await store.set("test", "value", expires_in=5)
  return None

async def getstore() -> int:
  expiry = await store.expires_in("test")
  return expiry
```


### Steps to reproduce

_No response_

### Screenshots

```bash
"![expiry](https://cdn.discordapp.com/attachments/919193495690936353/1105483460677734501/image.png)"
```


### Logs

_No response_

### Litestar Version

`litestar==2.0.0a5`

### Platform

- [ ] Linux
- [X] Mac
- [ ] Windows
- [X] Other (Please specify in the description above)
StaticFilesConfig and virtual directories
I'm trying to write a ``FileSystemProtocol`` to load files from the package data using [importlib_resources](https://importlib-resources.readthedocs.io/en/latest/using.html#). But because ``directories`` is defined as ``DirectoryPath``, pydantic checks if the given directories exist in the local filesystem. 

This is not generally true, especially in any kind of virtual filesystem (e.g. a zipped package). I think this condition should be relaxed to support virtual filesystems.

https://github.com/starlite-api/starlite/blob/9bb6dcd57c10a591377cf8e3a537e9292566d5b9/starlite/config/static_files.py#L32

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `litestar/stores/base.py`
Content:
```
1 from __future__ import annotations
2 
3 from abc import ABC, abstractmethod
4 from datetime import datetime, timedelta, timezone
5 from typing import TYPE_CHECKING, Optional
6 
7 from msgspec import Struct
8 from msgspec.msgpack import decode as msgpack_decode
9 from msgspec.msgpack import encode as msgpack_encode
10 
11 if TYPE_CHECKING:
12     from typing_extensions import Self
13 
14 
15 __all__ = ("Store", "NamespacedStore", "StorageObject")
16 
17 
18 class Store(ABC):  # pragma: no cover
19     """Thread and process safe asynchronous key/value store."""
20 
21     @abstractmethod
22     async def set(self, key: str, value: str | bytes, expires_in: int | timedelta | None = None) -> None:
23         """Set a value.
24 
25         Args:
26             key: Key to associate the value with
27             value: Value to store
28             expires_in: Time in seconds before the key is considered expired
29 
30         Returns:
31             ``None``
32         """
33         raise NotImplementedError
34 
35     @abstractmethod
36     async def get(self, key: str, renew_for: int | timedelta | None = None) -> bytes | None:
37         """Get a value.
38 
39         Args:
40             key: Key associated with the value
41             renew_for: If given and the value had an initial expiry time set, renew the
42                 expiry time for ``renew_for`` seconds. If the value has not been set
43                 with an expiry time this is a no-op
44 
45         Returns:
46             The value associated with ``key`` if it exists and is not expired, else
47             ``None``
48         """
49         raise NotImplementedError
50 
51     @abstractmethod
52     async def delete(self, key: str) -> None:
53         """Delete a value.
54 
55         If no such key exists, this is a no-op.
56 
57         Args:
58             key: Key of the value to delete
59         """
60         raise NotImplementedError
61 
62     @abstractmethod
63     async def delete_all(self) -> None:
64         """Delete all stored values."""
65         raise NotImplementedError
66 
67     @abstractmethod
68     async def exists(self, key: str) -> bool:
69         """Check if a given ``key`` exists."""
70         raise NotImplementedError
71 
72     @abstractmethod
73     async def expires_in(self, key: str) -> int | None:
74         """Get the time in seconds ``key`` expires in. If no such ``key`` exists or no
75         expiry time was set, return ``None``.
76         """
77         raise NotImplementedError
78 
79 
80 class NamespacedStore(Store):
81     """A subclass of :class:`Store`, offering hierarchical namespacing.
82 
83     Bulk actions on a parent namespace should affect all child namespaces, whereas other operations on all namespaces
84     should be isolated.
85     """
86 
87     @abstractmethod
88     def with_namespace(self, namespace: str) -> Self:
89         """Return a new instance of :class:`NamespacedStore`, which exists in a child namespace of the current namespace.
90         Bulk actions on the parent namespace should affect all child namespaces, whereas other operations on all
91         namespaces should be isolated.
92         """
93 
94 
95 class StorageObject(Struct):
96     """:class:`msgspec.Struct` to store serialized data alongside with their expiry time."""
97 
98     expires_at: Optional[datetime]  # noqa: UP007
99     data: bytes
100 
101     @classmethod
102     def new(cls, data: bytes, expires_in: int | timedelta | None) -> StorageObject:
103         """Construct a new :class:`StorageObject` instance."""
104         if expires_in is not None and not isinstance(expires_in, timedelta):
105             expires_in = timedelta(seconds=expires_in)
106         return cls(
107             data=data,
108             expires_at=(datetime.now(tz=timezone.utc) + expires_in) if expires_in else None,
109         )
110 
111     @property
112     def expired(self) -> bool:
113         """Return if the :class:`StorageObject` is expired"""
114         return self.expires_at is not None and datetime.now(tz=timezone.utc) >= self.expires_at
115 
116     @property
117     def expires_in(self) -> int:
118         """Return the expiry time of this ``StorageObject`` in seconds. If no expiry time
119         was set, return ``-1``.
120         """
121         if self.expires_at:
122             return (self.expires_at - datetime.now(tz=timezone.utc)).seconds
123         return -1
124 
125     def to_bytes(self) -> bytes:
126         """Encode the instance to bytes"""
127         return msgpack_encode(self)
128 
129     @classmethod
130     def from_bytes(cls, raw: bytes) -> StorageObject:
131         """Load a previously encoded with :meth:`StorageObject.to_bytes`"""
132         return msgpack_decode(raw, type=cls)
133
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/litestar/stores/base.py b/litestar/stores/base.py
--- a/litestar/stores/base.py
+++ b/litestar/stores/base.py
@@ -119,7 +119,7 @@
         was set, return ``-1``.
         """
         if self.expires_at:
-            return (self.expires_at - datetime.now(tz=timezone.utc)).seconds
+            return int(self.expires_at.timestamp() - datetime.now(tz=timezone.utc).timestamp())
         return -1
 
     def to_bytes(self) -> bytes:

{"golden_diff": "diff --git a/litestar/stores/base.py b/litestar/stores/base.py\n--- a/litestar/stores/base.py\n+++ b/litestar/stores/base.py\n@@ -119,7 +119,7 @@\n         was set, return ``-1``.\n         \"\"\"\n         if self.expires_at:\n-            return (self.expires_at - datetime.now(tz=timezone.utc)).seconds\n+            return int(self.expires_at.timestamp() - datetime.now(tz=timezone.utc).timestamp())\n         return -1\n \n     def to_bytes(self) -> bytes:\n", "issue": "Bug: StorageObject doesn't return < 0 when using expiry\n### Description\n\nWhen the stored value is expired, the returned interval is set to 86400 and will therefore not expire. \n\n### URL to code causing the issue\n\nhttps://github.com/litestar-org/litestar/blob/main/litestar/stores/base.py#L122\n\n### MCVE\n\n```python\nfrom pathlib import Path\r\nfrom litestar.stores.file import FileStore\r\n\r\nstore = FileStore(path=Path(\"test.db\"))\r\n\r\nasync def setstore() -> None:\r\n  await store.set(\"test\", \"value\", expires_in=5)\r\n  return None\r\n\r\nasync def getstore() -> int:\r\n  expiry = await store.expires_in(\"test\")\r\n  return expiry\n```\n\n\n### Steps to reproduce\n\n_No response_\n\n### Screenshots\n\n```bash\n\"![expiry](https://cdn.discordapp.com/attachments/919193495690936353/1105483460677734501/image.png)\"\n```\n\n\n### Logs\n\n_No response_\n\n### Litestar Version\n\n`litestar==2.0.0a5`\n\n### Platform\n\n- [ ] Linux\n- [X] Mac\n- [ ] Windows\n- [X] Other (Please specify in the description above)\nStaticFilesConfig and virtual directories\nI'm trying to write a ``FileSystemProtocol`` to load files from the package data using [importlib_resources](https://importlib-resources.readthedocs.io/en/latest/using.html#). But because ``directories`` is defined as ``DirectoryPath``, pydantic checks if the given directories exist in the local filesystem. \r\n\r\nThis is not generally true, especially in any kind of virtual filesystem (e.g. a zipped package). I think this condition should be relaxed to support virtual filesystems.\r\n\r\nhttps://github.com/starlite-api/starlite/blob/9bb6dcd57c10a591377cf8e3a537e9292566d5b9/starlite/config/static_files.py#L32\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom abc import ABC, abstractmethod\nfrom datetime import datetime, timedelta, timezone\nfrom typing import TYPE_CHECKING, Optional\n\nfrom msgspec import Struct\nfrom msgspec.msgpack import decode as msgpack_decode\nfrom msgspec.msgpack import encode as msgpack_encode\n\nif TYPE_CHECKING:\n    from typing_extensions import Self\n\n\n__all__ = (\"Store\", \"NamespacedStore\", \"StorageObject\")\n\n\nclass Store(ABC):  # pragma: no cover\n    \"\"\"Thread and process safe asynchronous key/value store.\"\"\"\n\n    @abstractmethod\n    async def set(self, key: str, value: str | bytes, expires_in: int | timedelta | None = None) -> None:\n        \"\"\"Set a value.\n\n        Args:\n            key: Key to associate the value with\n            value: Value to store\n            expires_in: Time in seconds before the key is considered expired\n\n        Returns:\n            ``None``\n        \"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    async def get(self, key: str, renew_for: int | timedelta | None = None) -> bytes | None:\n        \"\"\"Get a value.\n\n        Args:\n            key: Key associated with the value\n            renew_for: If given and the value had an initial expiry time set, renew the\n                expiry time for ``renew_for`` seconds. If the value has not been set\n                with an expiry time this is a no-op\n\n        Returns:\n            The value associated with ``key`` if it exists and is not expired, else\n            ``None``\n        \"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    async def delete(self, key: str) -> None:\n        \"\"\"Delete a value.\n\n        If no such key exists, this is a no-op.\n\n        Args:\n            key: Key of the value to delete\n        \"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    async def delete_all(self) -> None:\n        \"\"\"Delete all stored values.\"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    async def exists(self, key: str) -> bool:\n        \"\"\"Check if a given ``key`` exists.\"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    async def expires_in(self, key: str) -> int | None:\n        \"\"\"Get the time in seconds ``key`` expires in. If no such ``key`` exists or no\n        expiry time was set, return ``None``.\n        \"\"\"\n        raise NotImplementedError\n\n\nclass NamespacedStore(Store):\n    \"\"\"A subclass of :class:`Store`, offering hierarchical namespacing.\n\n    Bulk actions on a parent namespace should affect all child namespaces, whereas other operations on all namespaces\n    should be isolated.\n    \"\"\"\n\n    @abstractmethod\n    def with_namespace(self, namespace: str) -> Self:\n        \"\"\"Return a new instance of :class:`NamespacedStore`, which exists in a child namespace of the current namespace.\n        Bulk actions on the parent namespace should affect all child namespaces, whereas other operations on all\n        namespaces should be isolated.\n        \"\"\"\n\n\nclass StorageObject(Struct):\n    \"\"\":class:`msgspec.Struct` to store serialized data alongside with their expiry time.\"\"\"\n\n    expires_at: Optional[datetime]  # noqa: UP007\n    data: bytes\n\n    @classmethod\n    def new(cls, data: bytes, expires_in: int | timedelta | None) -> StorageObject:\n        \"\"\"Construct a new :class:`StorageObject` instance.\"\"\"\n        if expires_in is not None and not isinstance(expires_in, timedelta):\n            expires_in = timedelta(seconds=expires_in)\n        return cls(\n            data=data,\n            expires_at=(datetime.now(tz=timezone.utc) + expires_in) if expires_in else None,\n        )\n\n    @property\n    def expired(self) -> bool:\n        \"\"\"Return if the :class:`StorageObject` is expired\"\"\"\n        return self.expires_at is not None and datetime.now(tz=timezone.utc) >= self.expires_at\n\n    @property\n    def expires_in(self) -> int:\n        \"\"\"Return the expiry time of this ``StorageObject`` in seconds. If no expiry time\n        was set, return ``-1``.\n        \"\"\"\n        if self.expires_at:\n            return (self.expires_at - datetime.now(tz=timezone.utc)).seconds\n        return -1\n\n    def to_bytes(self) -> bytes:\n        \"\"\"Encode the instance to bytes\"\"\"\n        return msgpack_encode(self)\n\n    @classmethod\n    def from_bytes(cls, raw: bytes) -> StorageObject:\n        \"\"\"Load a previously encoded with :meth:`StorageObject.to_bytes`\"\"\"\n        return msgpack_decode(raw, type=cls)\n", "path": "litestar/stores/base.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom abc import ABC, abstractmethod\nfrom datetime import datetime, timedelta, timezone\nfrom typing import TYPE_CHECKING, Optional\n\nfrom msgspec import Struct\nfrom msgspec.msgpack import decode as msgpack_decode\nfrom msgspec.msgpack import encode as msgpack_encode\n\nif TYPE_CHECKING:\n    from typing_extensions import Self\n\n\n__all__ = (\"Store\", \"NamespacedStore\", \"StorageObject\")\n\n\nclass Store(ABC):  # pragma: no cover\n    \"\"\"Thread and process safe asynchronous key/value store.\"\"\"\n\n    @abstractmethod\n    async def set(self, key: str, value: str | bytes, expires_in: int | timedelta | None = None) -> None:\n        \"\"\"Set a value.\n\n        Args:\n            key: Key to associate the value with\n            value: Value to store\n            expires_in: Time in seconds before the key is considered expired\n\n        Returns:\n            ``None``\n        \"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    async def get(self, key: str, renew_for: int | timedelta | None = None) -> bytes | None:\n        \"\"\"Get a value.\n\n        Args:\n            key: Key associated with the value\n            renew_for: If given and the value had an initial expiry time set, renew the\n                expiry time for ``renew_for`` seconds. If the value has not been set\n                with an expiry time this is a no-op\n\n        Returns:\n            The value associated with ``key`` if it exists and is not expired, else\n            ``None``\n        \"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    async def delete(self, key: str) -> None:\n        \"\"\"Delete a value.\n\n        If no such key exists, this is a no-op.\n\n        Args:\n            key: Key of the value to delete\n        \"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    async def delete_all(self) -> None:\n        \"\"\"Delete all stored values.\"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    async def exists(self, key: str) -> bool:\n        \"\"\"Check if a given ``key`` exists.\"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    async def expires_in(self, key: str) -> int | None:\n        \"\"\"Get the time in seconds ``key`` expires in. If no such ``key`` exists or no\n        expiry time was set, return ``None``.\n        \"\"\"\n        raise NotImplementedError\n\n\nclass NamespacedStore(Store):\n    \"\"\"A subclass of :class:`Store`, offering hierarchical namespacing.\n\n    Bulk actions on a parent namespace should affect all child namespaces, whereas other operations on all namespaces\n    should be isolated.\n    \"\"\"\n\n    @abstractmethod\n    def with_namespace(self, namespace: str) -> Self:\n        \"\"\"Return a new instance of :class:`NamespacedStore`, which exists in a child namespace of the current namespace.\n        Bulk actions on the parent namespace should affect all child namespaces, whereas other operations on all\n        namespaces should be isolated.\n        \"\"\"\n\n\nclass StorageObject(Struct):\n    \"\"\":class:`msgspec.Struct` to store serialized data alongside with their expiry time.\"\"\"\n\n    expires_at: Optional[datetime]  # noqa: UP007\n    data: bytes\n\n    @classmethod\n    def new(cls, data: bytes, expires_in: int | timedelta | None) -> StorageObject:\n        \"\"\"Construct a new :class:`StorageObject` instance.\"\"\"\n        if expires_in is not None and not isinstance(expires_in, timedelta):\n            expires_in = timedelta(seconds=expires_in)\n        return cls(\n            data=data,\n            expires_at=(datetime.now(tz=timezone.utc) + expires_in) if expires_in else None,\n        )\n\n    @property\n    def expired(self) -> bool:\n        \"\"\"Return if the :class:`StorageObject` is expired\"\"\"\n        return self.expires_at is not None and datetime.now(tz=timezone.utc) >= self.expires_at\n\n    @property\n    def expires_in(self) -> int:\n        \"\"\"Return the expiry time of this ``StorageObject`` in seconds. If no expiry time\n        was set, return ``-1``.\n        \"\"\"\n        if self.expires_at:\n            return int(self.expires_at.timestamp() - datetime.now(tz=timezone.utc).timestamp())\n        return -1\n\n    def to_bytes(self) -> bytes:\n        \"\"\"Encode the instance to bytes\"\"\"\n        return msgpack_encode(self)\n\n    @classmethod\n    def from_bytes(cls, raw: bytes) -> StorageObject:\n        \"\"\"Load a previously encoded with :meth:`StorageObject.to_bytes`\"\"\"\n        return msgpack_decode(raw, type=cls)\n", "path": "litestar/stores/base.py"}]}