brainlessdb 0.7.0__tar.gz → 0.7.2__tar.gz

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.
Files changed (27) hide show
  1. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/CHANGELOG.md +14 -0
  2. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/PKG-INFO +20 -20
  3. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/README.md +19 -19
  4. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/brainlessdb/__init__.py +3 -3
  5. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/brainlessdb/collection.py +3 -3
  6. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/brainlessdb/struct.py +3 -3
  7. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/justfile +1 -1
  8. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/pyproject.toml +1 -1
  9. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/test_results.txt +40 -40
  10. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/tests/conftest.py +6 -6
  11. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/tests/test_collection.py +6 -6
  12. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/tests/test_deserialization.py +15 -15
  13. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/tests/test_fields.py +6 -6
  14. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/tests/test_load_errors.py +4 -4
  15. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/uv.lock +1 -1
  16. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/.gitignore +0 -0
  17. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/.python-version +0 -0
  18. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/brainlessdb/bucket.py +0 -0
  19. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/brainlessdb/client.py +0 -0
  20. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/brainlessdb/fields.py +0 -0
  21. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/cliff.toml +0 -0
  22. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/code_style_guide.md +0 -0
  23. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/tests/__init__.py +0 -0
  24. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/tests/mock_nats.py +0 -0
  25. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/tests/test_client.py +0 -0
  26. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/tests/test_sync.py +0 -0
  27. {brainlessdb-0.7.0 → brainlessdb-0.7.2}/tests/test_thread_safety.py +0 -0
@@ -3,6 +3,20 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
5
 
6
+ ## [0.7.2] - 2026-02-08
7
+
8
+ ### 🐛 Bug Fixes
9
+
10
+ - Commit pyproject.toml and brainlessdb/__init__.py on just release
11
+
12
+
13
+ ## [0.7.1] - 2026-02-08
14
+
15
+ ### Fchore
16
+
17
+ - Renamed BrainlessStruct to BrainlessBucket and NestedStruct to BrainlessStruct
18
+
19
+
6
20
  ## [0.7.0] - 2026-02-06
7
21
 
8
22
  ### 🚀 Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brainlessdb
3
- Version: 0.7.0
3
+ Version: 0.7.2
4
4
  Summary: Typed collections backed by NATS JetStream KV
5
5
  Author-email: "INSOFT s.r.o." <helpdesk@insoft.cz>
6
6
  License-Expression: MIT
@@ -18,9 +18,9 @@ Typed collections backed by NATS JetStream KV. In-memory with background sync.
18
18
  ```python
19
19
  from typing import Annotated
20
20
  from msgspec import Meta
21
- from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessStruct
21
+ from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessBucket
22
22
 
23
- class UserV1(BrainlessStruct):
23
+ class UserV1(BrainlessBucket):
24
24
  id: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.INDEX})]
25
25
  name: Annotated[str, Meta()] = ""
26
26
 
@@ -46,24 +46,24 @@ await db.stop()
46
46
 
47
47
  | Class | Use for | Has UUID | Stored in |
48
48
  |-------|---------|----------|-----------|
49
- | `BrainlessStruct` | Main entities (User, Order, etc.) | Yes | Own bucket(s) |
50
- | `NestedStruct` | Nested data, app-local data | No | Inside parent entity |
49
+ | `BrainlessBucket` | Main entities (User, Order, etc.) | Yes | Own bucket(s) |
50
+ | `BrainlessStruct` | Nested data, app-local data | No | Inside parent entity |
51
51
 
52
52
  ```python
53
- from brainlessdb import BrainlessStruct, NestedStruct
53
+ from brainlessdb import BrainlessBucket, BrainlessStruct
54
54
 
55
- # App-local data - NestedStruct (no UUID, not an entity)
56
- class UcsLocal(NestedStruct):
55
+ # App-local data - BrainlessStruct (no UUID, not an entity)
56
+ class UcsLocal(BrainlessStruct):
57
57
  sid: int = 0
58
58
  pointer: int = 0
59
59
 
60
- # Nested data - NestedStruct
61
- class Address(NestedStruct):
60
+ # Nested data - BrainlessStruct
61
+ class Address(BrainlessStruct):
62
62
  street: str = ""
63
63
  city: str = ""
64
64
 
65
- # Main entity - BrainlessStruct (has UUID, stored in NATS)
66
- class UserV1(BrainlessStruct):
65
+ # Main entity - BrainlessBucket (has UUID, stored in NATS)
66
+ class UserV1(BrainlessBucket):
67
67
  id: Annotated[int, Meta()]
68
68
  address: Optional[Address] = None # nested struct
69
69
  _: Optional[UcsLocal] = None # app-local struct
@@ -87,7 +87,7 @@ await brainlessdb.stop()
87
87
  Persistent data synced across all instances:
88
88
 
89
89
  ```python
90
- class UserV1(BrainlessStruct):
90
+ class UserV1(BrainlessBucket):
91
91
  id: Annotated[int, Meta()]
92
92
  name: Annotated[str, Meta()] = ""
93
93
  ```
@@ -96,7 +96,7 @@ class UserV1(BrainlessStruct):
96
96
  Ephemeral data (separate bucket, faster sync):
97
97
 
98
98
  ```python
99
- class UserV1(BrainlessStruct):
99
+ class UserV1(BrainlessBucket):
100
100
  id: Annotated[int, Meta()]
101
101
  status: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.STATE})] = 0
102
102
  ```
@@ -105,7 +105,7 @@ class UserV1(BrainlessStruct):
105
105
  Fast O(1) lookups:
106
106
 
107
107
  ```python
108
- class UserV1(BrainlessStruct):
108
+ class UserV1(BrainlessBucket):
109
109
  id: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.INDEX})]
110
110
  ```
111
111
 
@@ -113,7 +113,7 @@ class UserV1(BrainlessStruct):
113
113
  Enforces uniqueness constraint (also auto-indexed):
114
114
 
115
115
  ```python
116
- class UserV1(BrainlessStruct):
116
+ class UserV1(BrainlessBucket):
117
117
  email: Annotated[Optional[str], Meta(extra={"brainlessdb_flags": BrainlessDBFeat.UNIQUE})] = None
118
118
  ```
119
119
 
@@ -127,16 +127,16 @@ counter: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.INDEX |
127
127
  Data private to each namespace:
128
128
 
129
129
  ```python
130
- from brainlessdb import BrainlessStruct, NestedStruct
130
+ from brainlessdb import BrainlessBucket, BrainlessStruct
131
131
 
132
- class UcsLocal(NestedStruct):
132
+ class UcsLocal(BrainlessStruct):
133
133
  sid: int = 0
134
134
 
135
- class AriLocal(NestedStruct):
135
+ class AriLocal(BrainlessStruct):
136
136
  channel_id: str = ""
137
137
 
138
138
  # Entity with app-local field
139
- class UserV1(BrainlessStruct):
139
+ class UserV1(BrainlessBucket):
140
140
  id: Annotated[int, Meta()]
141
141
  _: Union[UcsLocal, AriLocal, None] = None
142
142
  ```
@@ -7,9 +7,9 @@ Typed collections backed by NATS JetStream KV. In-memory with background sync.
7
7
  ```python
8
8
  from typing import Annotated
9
9
  from msgspec import Meta
10
- from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessStruct
10
+ from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessBucket
11
11
 
12
- class UserV1(BrainlessStruct):
12
+ class UserV1(BrainlessBucket):
13
13
  id: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.INDEX})]
14
14
  name: Annotated[str, Meta()] = ""
15
15
 
@@ -35,24 +35,24 @@ await db.stop()
35
35
 
36
36
  | Class | Use for | Has UUID | Stored in |
37
37
  |-------|---------|----------|-----------|
38
- | `BrainlessStruct` | Main entities (User, Order, etc.) | Yes | Own bucket(s) |
39
- | `NestedStruct` | Nested data, app-local data | No | Inside parent entity |
38
+ | `BrainlessBucket` | Main entities (User, Order, etc.) | Yes | Own bucket(s) |
39
+ | `BrainlessStruct` | Nested data, app-local data | No | Inside parent entity |
40
40
 
41
41
  ```python
42
- from brainlessdb import BrainlessStruct, NestedStruct
42
+ from brainlessdb import BrainlessBucket, BrainlessStruct
43
43
 
44
- # App-local data - NestedStruct (no UUID, not an entity)
45
- class UcsLocal(NestedStruct):
44
+ # App-local data - BrainlessStruct (no UUID, not an entity)
45
+ class UcsLocal(BrainlessStruct):
46
46
  sid: int = 0
47
47
  pointer: int = 0
48
48
 
49
- # Nested data - NestedStruct
50
- class Address(NestedStruct):
49
+ # Nested data - BrainlessStruct
50
+ class Address(BrainlessStruct):
51
51
  street: str = ""
52
52
  city: str = ""
53
53
 
54
- # Main entity - BrainlessStruct (has UUID, stored in NATS)
55
- class UserV1(BrainlessStruct):
54
+ # Main entity - BrainlessBucket (has UUID, stored in NATS)
55
+ class UserV1(BrainlessBucket):
56
56
  id: Annotated[int, Meta()]
57
57
  address: Optional[Address] = None # nested struct
58
58
  _: Optional[UcsLocal] = None # app-local struct
@@ -76,7 +76,7 @@ await brainlessdb.stop()
76
76
  Persistent data synced across all instances:
77
77
 
78
78
  ```python
79
- class UserV1(BrainlessStruct):
79
+ class UserV1(BrainlessBucket):
80
80
  id: Annotated[int, Meta()]
81
81
  name: Annotated[str, Meta()] = ""
82
82
  ```
@@ -85,7 +85,7 @@ class UserV1(BrainlessStruct):
85
85
  Ephemeral data (separate bucket, faster sync):
86
86
 
87
87
  ```python
88
- class UserV1(BrainlessStruct):
88
+ class UserV1(BrainlessBucket):
89
89
  id: Annotated[int, Meta()]
90
90
  status: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.STATE})] = 0
91
91
  ```
@@ -94,7 +94,7 @@ class UserV1(BrainlessStruct):
94
94
  Fast O(1) lookups:
95
95
 
96
96
  ```python
97
- class UserV1(BrainlessStruct):
97
+ class UserV1(BrainlessBucket):
98
98
  id: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.INDEX})]
99
99
  ```
100
100
 
@@ -102,7 +102,7 @@ class UserV1(BrainlessStruct):
102
102
  Enforces uniqueness constraint (also auto-indexed):
103
103
 
104
104
  ```python
105
- class UserV1(BrainlessStruct):
105
+ class UserV1(BrainlessBucket):
106
106
  email: Annotated[Optional[str], Meta(extra={"brainlessdb_flags": BrainlessDBFeat.UNIQUE})] = None
107
107
  ```
108
108
 
@@ -116,16 +116,16 @@ counter: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.INDEX |
116
116
  Data private to each namespace:
117
117
 
118
118
  ```python
119
- from brainlessdb import BrainlessStruct, NestedStruct
119
+ from brainlessdb import BrainlessBucket, BrainlessStruct
120
120
 
121
- class UcsLocal(NestedStruct):
121
+ class UcsLocal(BrainlessStruct):
122
122
  sid: int = 0
123
123
 
124
- class AriLocal(NestedStruct):
124
+ class AriLocal(BrainlessStruct):
125
125
  channel_id: str = ""
126
126
 
127
127
  # Entity with app-local field
128
- class UserV1(BrainlessStruct):
128
+ class UserV1(BrainlessBucket):
129
129
  id: Annotated[int, Meta()]
130
130
  _: Union[UcsLocal, AriLocal, None] = None
131
131
  ```
@@ -1,19 +1,19 @@
1
1
  """Brainless DB - Typed collections backed by NATS JetStream KV."""
2
2
 
3
- __version__ = "0.7.0"
3
+ __version__ = "0.7.2"
4
4
 
5
5
  from typing import Any, Optional, TypeVar
6
6
 
7
7
  from .client import BrainlessDB
8
8
  from .collection import Collection, HasUUID
9
- from .struct import BrainlessDBFeat, BrainlessStruct, NestedStruct, UniqueConstraintError
9
+ from .struct import BrainlessDBFeat, BrainlessBucket, BrainlessStruct, UniqueConstraintError
10
10
 
11
11
  __all__ = [
12
12
  "__version__",
13
13
  "BrainlessDB",
14
14
  "BrainlessDBFeat",
15
+ "BrainlessBucket",
15
16
  "BrainlessStruct",
16
- "NestedStruct",
17
17
  "Collection",
18
18
  "HasUUID",
19
19
  "UniqueConstraintError",
@@ -11,7 +11,7 @@ import msgspec
11
11
  from .bucket import Bucket
12
12
  from .fields import analyze_fields
13
13
  from .struct import (
14
- BrainlessStruct,
14
+ BrainlessBucket,
15
15
  ConfigWrapper,
16
16
  UniqueConstraintError,
17
17
  _register,
@@ -45,8 +45,8 @@ class Collection(Generic[T]):
45
45
  """Collection of structs backed by NATS KV buckets."""
46
46
 
47
47
  def __init__(self, client: "BrainlessDB", cls: type[T]) -> None:
48
- if BrainlessStruct not in cls.__bases__:
49
- raise TypeError(f"{cls.__name__} must directly inherit from BrainlessStruct")
48
+ if BrainlessBucket not in cls.__bases__:
49
+ raise TypeError(f"{cls.__name__} must directly inherit from BrainlessBucket")
50
50
 
51
51
  self._client = client
52
52
  self._cls = cls
@@ -38,11 +38,11 @@ def _unregister(uuid: UUID) -> None:
38
38
  _registry.pop(uuid, None)
39
39
 
40
40
 
41
- class NestedStruct(Struct, tag=True, tag_field="TYPE"):
41
+ class BrainlessStruct(Struct, tag=True, tag_field="TYPE"):
42
42
  """Base struct for nested/embedded types."""
43
43
 
44
44
 
45
- class BrainlessStruct(Struct, kw_only=True, tag=True, tag_field="TYPE"):
45
+ class BrainlessBucket(Struct, kw_only=True, tag=True, tag_field="TYPE"):
46
46
  """Base struct for brainlessdb entities."""
47
47
 
48
48
  _uuid: UUID = field(default_factory=uuid1)
@@ -57,7 +57,7 @@ class BrainlessStruct(Struct, kw_only=True, tag=True, tag_field="TYPE"):
57
57
  if collection:
58
58
  collection.add(self)
59
59
 
60
- def update(self, data: dict) -> "BrainlessStruct":
60
+ def update(self, data: dict) -> "BrainlessBucket":
61
61
  """Update fields from dict, supports nested structs."""
62
62
  for key, value in data.items():
63
63
  if not hasattr(self, key):
@@ -6,7 +6,7 @@ create-changelog:
6
6
  release: create-changelog
7
7
  awk -i inplace '{ sub(/^version = "[0-9]+\.[0-9]+\.[0-9]+"/, "version = \"{{next_version}}\"") }; { print }' pyproject.toml
8
8
  awk -i inplace '{ sub(/^__version__ = "[0-9]+\.[0-9]+\.[0-9]+"/, "__version__ = \"{{next_version}}\"") }; { print }' brainlessdb/__init__.py
9
- git add --ignore-errors CHANGELOG.md
9
+ git add --ignore-errors CHANGELOG.md pyproject.toml uv.lock brainlessdb/__init__.py
10
10
  git commit -m {{next_version}}
11
11
  git tag -a {{next_version}} -m {{next_version}}
12
12
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "brainlessdb"
3
- version = "0.7.0"
3
+ version = "0.7.2"
4
4
  description = "Typed collections backed by NATS JetStream KV"
5
5
  authors = [
6
6
  {name = "INSOFT s.r.o.", email = "helpdesk@insoft.cz"}
@@ -425,14 +425,14 @@ self = <tests.test_deserialization.TestRealWorldUserPattern object at 0x720273f1
425
425
  """Test Optional[Annotated[int, Meta(...)]] pattern like queue_reason."""
426
426
  from enum import IntEnum
427
427
  import msgspec
428
- from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessStruct
428
+ from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessBucket
429
429
  from brainlessdb.struct import ConfigWrapper
430
-
430
+
431
431
  class Status(IntEnum):
432
432
  OFFLINE = 0
433
433
  ONLINE = 1
434
-
435
- class UserLike(BrainlessStruct):
434
+
435
+ class UserLike(BrainlessBucket):
436
436
  id: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.INDEX})] = 0
437
437
  group_id: int = 0
438
438
  # Pattern from queue_reason - Optional[Annotated[int, ...]]
@@ -440,7 +440,7 @@ self = <tests.test_deserialization.TestRealWorldUserPattern object at 0x720273f1
440
440
  queue_status_changed: Optional[Annotated[int, Meta(description="")]] = None
441
441
  # State field with enum
442
442
  status: Annotated[Status, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.STATE})] = Status.OFFLINE
443
-
443
+
444
444
  db = BrainlessDB(namespace="test")
445
445
  > coll = await db.collection(UserLike)
446
446
  E TypeError: object Collection can't be used in 'await' expression
@@ -454,17 +454,17 @@ self = <tests.test_deserialization.TestRealWorldUserPattern object at 0x720273f1
454
454
  async def test_nested_struct_pattern(self):
455
455
  """Test nested struct like AgentChannelsV1."""
456
456
  import msgspec
457
- from brainlessdb import BrainlessDB, BrainlessStruct
457
+ from brainlessdb import BrainlessDB, BrainlessBucket
458
458
  from brainlessdb.struct import ConfigWrapper
459
-
459
+
460
460
  class Channels(Struct):
461
461
  voice: int = 0
462
462
  chat: int = 0
463
-
464
- class UserWithChannels(BrainlessStruct):
463
+
464
+ class UserWithChannels(BrainlessBucket):
465
465
  id: int = 0
466
466
  channels: Channels = field(default_factory=Channels)
467
-
467
+
468
468
  db = BrainlessDB(namespace="test")
469
469
  > coll = await db.collection(UserWithChannels)
470
470
  E TypeError: object Collection can't be used in 'await' expression
@@ -478,17 +478,17 @@ self = <tests.test_deserialization.TestRealWorldUserPattern object at 0x720273f1
478
478
  async def test_vcard_list_pattern(self):
479
479
  """Test list of nested structs like vcard: list[VCardV1]."""
480
480
  import msgspec
481
- from brainlessdb import BrainlessDB, BrainlessStruct
481
+ from brainlessdb import BrainlessDB, BrainlessBucket
482
482
  from brainlessdb.struct import ConfigWrapper
483
-
483
+
484
484
  class VCard(Struct):
485
485
  name: str = ""
486
486
  value: str = ""
487
-
488
- class UserWithVCard(BrainlessStruct):
487
+
488
+ class UserWithVCard(BrainlessBucket):
489
489
  id: int = 0
490
490
  vcard: Optional[list[VCard]] = None
491
-
491
+
492
492
  db = BrainlessDB(namespace="test")
493
493
  > coll = await db.collection(UserWithVCard)
494
494
  E TypeError: object Collection can't be used in 'await' expression
@@ -501,18 +501,18 @@ self = <tests.test_deserialization.TestLocalClassDetection object at 0x720273f19
501
501
  @pytest.mark.asyncio
502
502
  async def test_optional_annotated_union_pattern(self):
503
503
  """Test Optional[Annotated[Union[A, B], Meta()]] pattern from UserV2."""
504
- from brainlessdb import BrainlessDB, BrainlessStruct
505
-
504
+ from brainlessdb import BrainlessDB, BrainlessBucket
505
+
506
506
  class AriLocal(Struct):
507
507
  counter: int = 0
508
-
508
+
509
509
  class UcsLocal(Struct):
510
510
  counter: int = 0
511
-
512
- class UserWithUnionLocal(BrainlessStruct):
511
+
512
+ class UserWithUnionLocal(BrainlessBucket):
513
513
  id: int = 0
514
514
  _: Optional[Annotated[Union[UcsLocal, AriLocal], Meta()]] = None
515
-
515
+
516
516
  # Test with "ari" namespace - should find AriLocal
517
517
  db_ari = BrainlessDB(namespace="ari")
518
518
  > coll_ari = await db_ari.collection(UserWithUnionLocal)
@@ -526,15 +526,15 @@ self = <tests.test_deserialization.TestLocalClassDetection object at 0x720273f19
526
526
  @pytest.mark.asyncio
527
527
  async def test_optional_single_class_pattern(self):
528
528
  """Test Optional[LocalClass] pattern."""
529
- from brainlessdb import BrainlessDB, BrainlessStruct
530
-
529
+ from brainlessdb import BrainlessDB, BrainlessBucket
530
+
531
531
  class TestLocal(Struct):
532
532
  value: int = 0
533
-
534
- class UserWithLocal(BrainlessStruct):
533
+
534
+ class UserWithLocal(BrainlessBucket):
535
535
  id: int = 0
536
536
  _: Optional[TestLocal] = None
537
-
537
+
538
538
  db = BrainlessDB(namespace="test")
539
539
  > coll = await db.collection(UserWithLocal)
540
540
  E TypeError: object Collection can't be used in 'await' expression
@@ -547,18 +547,18 @@ self = <tests.test_deserialization.TestLocalClassDetection object at 0x720273f12
547
547
  @pytest.mark.asyncio
548
548
  async def test_union_without_optional_pattern(self):
549
549
  """Test Union[A, B] (without Optional) pattern."""
550
- from brainlessdb import BrainlessDB, BrainlessStruct
551
-
550
+ from brainlessdb import BrainlessDB, BrainlessBucket
551
+
552
552
  class AriData(Struct):
553
553
  x: int = 0
554
-
554
+
555
555
  class UcsData(Struct):
556
556
  x: int = 0
557
-
558
- class UserUnion(BrainlessStruct):
557
+
558
+ class UserUnion(BrainlessBucket):
559
559
  id: int = 0
560
560
  _: Union[UcsData, AriData] = field(default_factory=UcsData)
561
-
561
+
562
562
  db = BrainlessDB(namespace="ari")
563
563
  > coll = await db.collection(UserUnion)
564
564
  E TypeError: object Collection can't be used in 'await' expression
@@ -572,12 +572,12 @@ self = <tests.test_sync.TestMultiLocationSync object at 0x720273f197c0>
572
572
  async def test_two_locations_see_same_data(self):
573
573
  """Both locations can read data written by either."""
574
574
  nats = MockNats()
575
-
575
+
576
576
  db1 = BrainlessDB(nats, namespace="loc1", flush_interval=0)
577
577
  db2 = BrainlessDB(nats, namespace="loc2", flush_interval=0)
578
578
  await db1.start()
579
579
  await db2.start()
580
-
580
+
581
581
  > users1 = await db1.collection(UserV1)
582
582
  E TypeError: object Collection can't be used in 'await' expression
583
583
 
@@ -590,12 +590,12 @@ self = <tests.test_sync.TestMultiLocationSync object at 0x720273f125b0>
590
590
  async def test_watch_receives_remote_changes(self):
591
591
  """Watch fires when other location makes changes."""
592
592
  nats = MockNats()
593
-
593
+
594
594
  db1 = BrainlessDB(nats, namespace="loc1", flush_interval=0)
595
595
  db2 = BrainlessDB(nats, namespace="loc2", flush_interval=0)
596
596
  await db1.start()
597
597
  await db2.start()
598
-
598
+
599
599
  > users1 = await db1.collection(UserV1)
600
600
  E TypeError: object Collection can't be used in 'await' expression
601
601
 
@@ -608,10 +608,10 @@ self = <tests.test_sync.TestMultiLocationSync object at 0x720273eadd00>
608
608
  async def test_location_tracked_in_metadata(self):
609
609
  """Config bucket tracks which location made the change."""
610
610
  nats = MockNats()
611
-
611
+
612
612
  db1 = BrainlessDB(nats, namespace="loc1", flush_interval=0)
613
613
  await db1.start()
614
-
614
+
615
615
  > users1 = await db1.collection(UserV1)
616
616
  E TypeError: object Collection can't be used in 'await' expression
617
617
 
@@ -624,12 +624,12 @@ self = <tests.test_sync.TestMultiLocationSync object at 0x720273ead040>
624
624
  async def test_remote_delete_fires_event(self):
625
625
  """Delete from one location fires event on other."""
626
626
  nats = MockNats()
627
-
627
+
628
628
  db1 = BrainlessDB(nats, namespace="loc1", flush_interval=0)
629
629
  db2 = BrainlessDB(nats, namespace="loc2", flush_interval=0)
630
630
  await db1.start()
631
631
  await db2.start()
632
-
632
+
633
633
  > users1 = await db1.collection(UserV1)
634
634
  E TypeError: object Collection can't be used in 'await' expression
635
635
 
@@ -5,10 +5,10 @@ from typing import Annotated, Optional
5
5
  import pytest
6
6
  from msgspec import Meta
7
7
 
8
- from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessStruct
8
+ from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessBucket
9
9
 
10
10
 
11
- class UserV1(BrainlessStruct):
11
+ class UserV1(BrainlessBucket):
12
12
  """Test user struct with indexed username."""
13
13
 
14
14
  id: Annotated[int, Meta()] = 0
@@ -20,21 +20,21 @@ class UserV1(BrainlessStruct):
20
20
  active: Annotated[bool, Meta()] = True
21
21
 
22
22
 
23
- class ChannelV1(BrainlessStruct):
23
+ class ChannelV1(BrainlessBucket):
24
24
  """Test channel struct."""
25
25
 
26
26
  id: Annotated[str, Meta()] = ""
27
27
  name: Annotated[str, Meta()] = ""
28
28
 
29
29
 
30
- class AgentV1(BrainlessStruct):
30
+ class AgentV1(BrainlessBucket):
31
31
  """Test agent struct."""
32
32
 
33
33
  id: Annotated[int, Meta()] = 0
34
34
  channel: Optional[ChannelV1] = None
35
35
 
36
36
 
37
- class QueueItemV1(BrainlessStruct):
37
+ class QueueItemV1(BrainlessBucket):
38
38
  """Test queue item with nested structs."""
39
39
 
40
40
  inbound_id: Annotated[
@@ -45,7 +45,7 @@ class QueueItemV1(BrainlessStruct):
45
45
  agents: Optional[AgentV1] = None
46
46
 
47
47
 
48
- class UniqueUserV1(BrainlessStruct):
48
+ class UniqueUserV1(BrainlessBucket):
49
49
  """Test struct with UNIQUE field."""
50
50
 
51
51
  id: int = 0
@@ -525,9 +525,9 @@ class TestOptionalFieldRoundTrip:
525
525
  """Optional field set to None must be stored and restored."""
526
526
  from typing import Optional
527
527
 
528
- from brainlessdb import BrainlessDB, BrainlessStruct
528
+ from brainlessdb import BrainlessDB, BrainlessBucket
529
529
 
530
- class DeviceV1(BrainlessStruct):
530
+ class DeviceV1(BrainlessBucket):
531
531
  name: str = ""
532
532
  host_override: Optional[str] = None
533
533
 
@@ -553,10 +553,10 @@ class TestOptionalFieldRoundTrip:
553
553
 
554
554
  import msgspec
555
555
 
556
- from brainlessdb import BrainlessDB, BrainlessStruct
556
+ from brainlessdb import BrainlessDB, BrainlessBucket
557
557
  from brainlessdb.struct import ConfigWrapper
558
558
 
559
- class DeviceV1(BrainlessStruct):
559
+ class DeviceV1(BrainlessBucket):
560
560
  name: str = ""
561
561
  host_override: Optional[str] = None
562
562
 
@@ -582,10 +582,10 @@ class TestOptionalFieldRoundTrip:
582
582
  """Full flush/reload through mock NATS preserves None fields."""
583
583
  from typing import Optional
584
584
 
585
- from brainlessdb import BrainlessDB, BrainlessStruct
585
+ from brainlessdb import BrainlessDB, BrainlessBucket
586
586
  from tests.mock_nats import MockNats
587
587
 
588
- class DeviceV1(BrainlessStruct):
588
+ class DeviceV1(BrainlessBucket):
589
589
  name: str = ""
590
590
  host_override: Optional[str] = None
591
591
 
@@ -9,7 +9,7 @@ from typing import Annotated, Optional, Union
9
9
  import pytest
10
10
  from msgspec import Meta, Struct, field
11
11
 
12
- from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessStruct
12
+ from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessBucket
13
13
  from brainlessdb.collection import Collection
14
14
 
15
15
 
@@ -20,7 +20,7 @@ class LocalData(Struct):
20
20
  count: int = 0
21
21
 
22
22
 
23
- class EntityWithIntFields(BrainlessStruct):
23
+ class EntityWithIntFields(BrainlessBucket):
24
24
  """Entity with various int fields in different buckets."""
25
25
 
26
26
  # Config field (no flags)
@@ -48,7 +48,7 @@ class EntityWithIntFields(BrainlessStruct):
48
48
  _: Optional[LocalData] = None
49
49
 
50
50
 
51
- class EntityMixedTypes(BrainlessStruct):
51
+ class EntityMixedTypes(BrainlessBucket):
52
52
  """Entity with mixed types to test type preservation."""
53
53
 
54
54
  int_field: int = 0
@@ -427,14 +427,14 @@ class TestRealWorldUserPattern:
427
427
  """Test Optional[Annotated[int, Meta(...)]] pattern like queue_reason."""
428
428
  from enum import IntEnum
429
429
  import msgspec
430
- from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessStruct
430
+ from brainlessdb import BrainlessDB, BrainlessDBFeat, BrainlessBucket
431
431
  from brainlessdb.struct import ConfigWrapper
432
432
 
433
433
  class Status(IntEnum):
434
434
  OFFLINE = 0
435
435
  ONLINE = 1
436
436
 
437
- class UserLike(BrainlessStruct):
437
+ class UserLike(BrainlessBucket):
438
438
  id: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.INDEX})] = 0
439
439
  group_id: int = 0
440
440
  # Pattern from queue_reason - Optional[Annotated[int, ...]]
@@ -490,14 +490,14 @@ class TestRealWorldUserPattern:
490
490
  async def test_nested_struct_pattern(self):
491
491
  """Test nested struct like AgentChannelsV1."""
492
492
  import msgspec
493
- from brainlessdb import BrainlessDB, BrainlessStruct
493
+ from brainlessdb import BrainlessDB, BrainlessBucket
494
494
  from brainlessdb.struct import ConfigWrapper
495
495
 
496
496
  class Channels(Struct):
497
497
  voice: int = 0
498
498
  chat: int = 0
499
499
 
500
- class UserWithChannels(BrainlessStruct):
500
+ class UserWithChannels(BrainlessBucket):
501
501
  id: int = 0
502
502
  channels: Channels = field(default_factory=Channels)
503
503
 
@@ -526,14 +526,14 @@ class TestRealWorldUserPattern:
526
526
  async def test_vcard_list_pattern(self):
527
527
  """Test list of nested structs like vcard: list[VCardV1]."""
528
528
  import msgspec
529
- from brainlessdb import BrainlessDB, BrainlessStruct
529
+ from brainlessdb import BrainlessDB, BrainlessBucket
530
530
  from brainlessdb.struct import ConfigWrapper
531
531
 
532
532
  class VCard(Struct):
533
533
  name: str = ""
534
534
  value: str = ""
535
535
 
536
- class UserWithVCard(BrainlessStruct):
536
+ class UserWithVCard(BrainlessBucket):
537
537
  id: int = 0
538
538
  vcard: Optional[list[VCard]] = None
539
539
 
@@ -568,7 +568,7 @@ class TestLocalClassDetection:
568
568
  @pytest.mark.asyncio
569
569
  async def test_optional_annotated_union_pattern(self):
570
570
  """Test Optional[Annotated[Union[A, B], Meta()]] pattern from UserV2."""
571
- from brainlessdb import BrainlessDB, BrainlessStruct
571
+ from brainlessdb import BrainlessDB, BrainlessBucket
572
572
 
573
573
  class AriLocal(Struct):
574
574
  counter: int = 0
@@ -576,7 +576,7 @@ class TestLocalClassDetection:
576
576
  class UcsLocal(Struct):
577
577
  counter: int = 0
578
578
 
579
- class UserWithUnionLocal(BrainlessStruct):
579
+ class UserWithUnionLocal(BrainlessBucket):
580
580
  id: int = 0
581
581
  _: Optional[Annotated[Union[UcsLocal, AriLocal], Meta()]] = None
582
582
 
@@ -593,12 +593,12 @@ class TestLocalClassDetection:
593
593
  @pytest.mark.asyncio
594
594
  async def test_optional_single_class_pattern(self):
595
595
  """Test Optional[LocalClass] pattern."""
596
- from brainlessdb import BrainlessDB, BrainlessStruct
596
+ from brainlessdb import BrainlessDB, BrainlessBucket
597
597
 
598
598
  class TestLocal(Struct):
599
599
  value: int = 0
600
600
 
601
- class UserWithLocal(BrainlessStruct):
601
+ class UserWithLocal(BrainlessBucket):
602
602
  id: int = 0
603
603
  _: Optional[TestLocal] = None
604
604
 
@@ -609,7 +609,7 @@ class TestLocalClassDetection:
609
609
  @pytest.mark.asyncio
610
610
  async def test_union_without_optional_pattern(self):
611
611
  """Test Union[A, B] (without Optional) pattern."""
612
- from brainlessdb import BrainlessDB, BrainlessStruct
612
+ from brainlessdb import BrainlessDB, BrainlessBucket
613
613
 
614
614
  class AriData(Struct):
615
615
  x: int = 0
@@ -617,7 +617,7 @@ class TestLocalClassDetection:
617
617
  class UcsData(Struct):
618
618
  x: int = 0
619
619
 
620
- class UserUnion(BrainlessStruct):
620
+ class UserUnion(BrainlessBucket):
621
621
  id: int = 0
622
622
  _: Union[UcsData, AriData] = field(default_factory=UcsData)
623
623
 
@@ -4,7 +4,7 @@ from typing import Annotated, Optional, Union
4
4
 
5
5
  from msgspec import Meta, Struct
6
6
 
7
- from brainlessdb import BrainlessDBFeat, BrainlessStruct
7
+ from brainlessdb import BrainlessDBFeat, BrainlessBucket
8
8
  from brainlessdb.fields import analyze_fields
9
9
 
10
10
 
@@ -17,14 +17,14 @@ class AriV1(Struct):
17
17
  channel_id: str = ""
18
18
 
19
19
 
20
- class SimpleV1(BrainlessStruct):
20
+ class SimpleV1(BrainlessBucket):
21
21
  """Simple struct with no state or app-local."""
22
22
 
23
23
  id: Annotated[int, Meta()] = 0
24
24
  name: Annotated[str, Meta()] = ""
25
25
 
26
26
 
27
- class WithStateV1(BrainlessStruct):
27
+ class WithStateV1(BrainlessBucket):
28
28
  """Struct with state fields."""
29
29
 
30
30
  id: Annotated[int, Meta()] = 0
@@ -39,21 +39,21 @@ class WithStateV1(BrainlessStruct):
39
39
  ] = 0
40
40
 
41
41
 
42
- class WithLocalV1(BrainlessStruct):
42
+ class WithLocalV1(BrainlessBucket):
43
43
  """Struct with app-local field."""
44
44
 
45
45
  id: Annotated[int, Meta()] = 0
46
46
  _: Optional[UcsV1] = None
47
47
 
48
48
 
49
- class WithUnionLocalV1(BrainlessStruct):
49
+ class WithUnionLocalV1(BrainlessBucket):
50
50
  """Struct with Union app-local field."""
51
51
 
52
52
  id: Annotated[int, Meta()] = 0
53
53
  _: Union[UcsV1, AriV1, None] = None
54
54
 
55
55
 
56
- class FullV1(BrainlessStruct):
56
+ class FullV1(BrainlessBucket):
57
57
  """Struct with config, state, and app-local."""
58
58
 
59
59
  id: Annotated[int, Meta()] = 0
@@ -125,9 +125,9 @@ class TestCorruptStateBucket:
125
125
 
126
126
  from msgspec import Meta
127
127
 
128
- from brainlessdb import BrainlessDBFeat, BrainlessStruct
128
+ from brainlessdb import BrainlessDBFeat, BrainlessBucket
129
129
 
130
- class AgentV1(BrainlessStruct):
130
+ class AgentV1(BrainlessBucket):
131
131
  id: int = 0
132
132
  status: Annotated[int, Meta(extra={"brainlessdb_flags": BrainlessDBFeat.STATE})] = 0
133
133
 
@@ -171,12 +171,12 @@ class TestCorruptLocalBucket:
171
171
 
172
172
  from msgspec import Struct
173
173
 
174
- from brainlessdb import BrainlessDB, BrainlessStruct
174
+ from brainlessdb import BrainlessDB, BrainlessBucket
175
175
 
176
176
  class TestLocal(Struct):
177
177
  sid: int = 0
178
178
 
179
- class ItemV1(BrainlessStruct):
179
+ class ItemV1(BrainlessBucket):
180
180
  id: int = 0
181
181
  _: Optional[TestLocal] = None
182
182
 
@@ -17,7 +17,7 @@ wheels = [
17
17
 
18
18
  [[package]]
19
19
  name = "brainlessdb"
20
- version = "0.4.1"
20
+ version = "0.7.0"
21
21
  source = { editable = "." }
22
22
  dependencies = [
23
23
  { name = "msgspec" },
File without changes
File without changes
File without changes