Skip to content

Commit 3acfc31

Browse files
committed
docs: add Visnalize sponsor and update CLAUDE.md with filter system learnings
1 parent 10efeab commit 3acfc31

File tree

3 files changed

+13
-7
lines changed

3 files changed

+13
-7
lines changed

CLAUDE.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ Plugin bundles under `Plugins/`:
9191
| DynamoDBDriverPlugin | DynamoDB | (AWS SDK) | Built-in |
9292
| BigQueryDriverPlugin | BigQuery | (URLSession REST) | Registry |
9393

94-
When adding a new driver: create a new plugin bundle under `Plugins/`, implement `DriverPlugin` + `PluginDatabaseDriver`, add target to pbxproj. See `docs/development/plugin-system/` for details.
94+
When adding a new driver: create a new plugin bundle under `Plugins/`, implement `DriverPlugin` + `PluginDatabaseDriver`, add target to pbxproj, add `DatabaseType` static constant, add case to `resolve_plugin_info()` in `.github/workflows/build-plugin.yml`, add row to `docs/index.mdx` supported databases table, and add CHANGELOG entry. See `docs/development/plugin-system/` for details.
9595

9696
When adding a new method to the driver protocol: add to `PluginDatabaseDriver` (with default implementation), then update `PluginDriverAdapter` to bridge it to `DatabaseDriver`.
9797

98-
**PluginKit ABI versioning**: When `DriverPlugin` or `PluginDatabaseDriver` protocol changes (new methods, changed signatures), bump `currentPluginKitVersion` in `PluginManager.swift` AND `TableProPluginKitVersion` in every plugin's `Info.plist`. Stale user-installed plugins with mismatched versions crash on load with `EXC_BAD_INSTRUCTION` (not catchable in Swift).
98+
**PluginKit ABI versioning**: When `DriverPlugin` or `PluginDatabaseDriver` protocol changes (new methods, changed signatures), bump `currentPluginKitVersion` in `PluginManager.swift` AND `TableProPluginKitVersion` in every plugin's `Info.plist`. Stale user-installed plugins with mismatched versions crash on load with `EXC_BAD_INSTRUCTION` (not catchable in Swift). Removing protocol methods that have default `nil` implementations does NOT require a version bump — old plugins have dead code, new plugins fall back to defaults.
9999

100100
### DatabaseType (String-Based Struct)
101101

@@ -124,6 +124,8 @@ When adding a new method to the driver protocol: add to `PluginDatabaseDriver` (
124124

125125
`MainContentCoordinator` is the central coordinator, split across 7+ extension files in `Views/Main/Extensions/` (e.g., `+Alerts`, `+Filtering`, `+Pagination`, `+RowOperations`). When adding coordinator functionality, add a new extension file rather than growing the main file.
126126

127+
**Tab replacement guard**: `openTableTab` checks for active work (unsaved edits, applied filters, sorting) before replacing the current tab. Tabs with active work open a new native window tab instead. This check runs before the preview tab branch.
128+
127129
### Source Organization
128130

129131
`Core/Services/` is split into domain subdirectories:
@@ -150,7 +152,8 @@ When adding a new method to the driver protocol: add to `PluginDatabaseDriver` (
150152
| User preferences | UserDefaults | `AppSettingsStorage` / `AppSettingsManager` |
151153
| Query history | SQLite FTS5 | `QueryHistoryStorage` |
152154
| Tab state | JSON persistence | `TabPersistenceService` / `TabStateStorage` |
153-
| Filter presets || `FilterSettingsStorage` |
155+
| Filter presets | UserDefaults | `FilterSettingsStorage` |
156+
| Per-table filters | UserDefaults | `FilterSettingsStorage` (saves `appliedFilters` only) |
154157

155158
### Logging
156159

@@ -198,14 +201,14 @@ These are **non-negotiable** — never skip them:
198201

199202
1. **CHANGELOG.md**: Update under `[Unreleased]` section (Added/Fixed/Changed) for new features and notable changes. But do **not** add a "Fixed" entry for fixing something that is itself still unreleased if a feature under `[Unreleased]` has a bug, just fix it without adding another CHANGELOG entry. "Fixed" entries are only for bugs in already-released features. Documentation-only changes (`docs/`) do **not** need a CHANGELOG entry.
200203

201-
2. **Localization**: Use `String(localized:)` for new user-facing strings in computed properties, AppKit code, alerts, and error descriptions. SwiftUI view literals (`Text("literal")`, `Button("literal")`) auto-localize. Do NOT localize technical terms (font names, database types, SQL keywords, encoding names).
204+
2. **Localization**: Use `String(localized:)` for new user-facing strings in computed properties, AppKit code, alerts, and error descriptions. SwiftUI view literals (`Text("literal")`, `Button("literal")`) auto-localize. Do NOT localize technical terms (font names, database types, SQL keywords, encoding names). Never use `String(localized:)` with string interpolation `String(localized: "Preview \(name)")` creates a dynamic key that never matches the strings catalog. Use static keys or `String(format: String(localized: "Preview %@"), name)`.
202205

203206
3. **Documentation**: Update docs in `docs/` (Mintlify-based) when adding/changing features. Key mappings:
204207
- New keyboard shortcuts → `docs/features/keyboard-shortcuts.mdx`
205208
- UI/feature changes → relevant `docs/features/*.mdx` page
206209
- Settings changes → `docs/customization/settings.mdx`
207210
- Database driver changes → `docs/databases/*.mdx`
208-
- Update both English (`docs/`) and Vietnamese (`docs/vi/`) pages
211+
- Update English docs in `docs/` (no Vietnamese `docs/vi/` directory currently exists)
209212
210213
4. **Test-first correctness**: When tests fail, fix the **source code** — never adjust tests to match incorrect output. Tests define expected behavior.
211214
@@ -229,6 +232,7 @@ These are **non-negotiable** — never skip them:
229232
230233
These have caused real production bugs — be aware when working in editor/autocomplete/persistence code:
231234
235+
- **Never use `ForEach($bindable.array) { $item in }`** on `@Observable` arrays that can be cleared externally — index-based bindings crash with out-of-bounds when the array shrinks during SwiftUI evaluation. Use `ForEach(array) { item in` with a manual `Binding` via `binding(for: item)` instead.
232236
- **Never use `string.count`** on large strings — O(n) in Swift. Use `(string as NSString).length` for O(1).
233237
- **Never use `string.index(string.startIndex, offsetBy:)` in loops** on bridged NSStrings — O(n) per call. Use `(string as NSString).character(at:)` for O(1) random access.
234238
- **Never call `ensureLayout(forCharacterRange:)`** — defeats `allowsNonContiguousLayout`. Let layout manager queries trigger lazy local layout.

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ Thanks to these amazing people for supporting TablePro:
5050

5151
- **[Dwarves Foundation](https://dwarves.foundation/?ref=tablepro)**
5252
- **[Nimbus](https://getnimbus.io?ref=tablepro)**
53-
- **[Huy TQ](https://github.com/imhuytq)** — Apple Developer Program sponsor
53+
- **[Visnalize](https://visnalize.com?ref=tablepro)**
54+
- **[Huy TQ](https://github.com/imhuytq)**
5455
- **[Unikorn](https://unikorn.vn?ref=tablepro)**
5556

5657
## Star History

README.vi.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ Cảm ơn những người tuyệt vời đã hỗ trợ TablePro:
4646

4747
- **[Dwarves Foundation](https://dwarves.foundation/?ref=tablepro)**
4848
- **[Nimbus](https://getnimbus.io?ref=tablepro)**
49-
- **[Huy TQ](https://github.com/imhuytq)** — Tài trợ Apple Developer Program
49+
- **[Visnalize](https://visnalize.com?ref=tablepro)**
50+
- **[Huy TQ](https://github.com/imhuytq)**
5051
- **[Unikorn](https://unikorn.vn?ref=tablepro)**
5152

5253
## Lịch sử Star

0 commit comments

Comments
 (0)