strata-storage 2.0.3 → 2.0.4
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.
- package/android/src/main/java/com/strata/storage/EncryptedStorage.java +44 -3
- package/android/src/main/java/com/strata/storage/SQLiteStorage.java +35 -5
- package/android/src/main/java/com/strata/storage/SharedPreferencesStorage.java +43 -3
- package/android/src/main/java/com/stratastorage/StrataStoragePlugin.java +12 -3
- package/dist/android/src/main/java/com/strata/storage/EncryptedStorage.java +44 -3
- package/dist/android/src/main/java/com/strata/storage/SQLiteStorage.java +35 -5
- package/dist/android/src/main/java/com/strata/storage/SharedPreferencesStorage.java +43 -3
- package/dist/android/src/main/java/com/stratastorage/StrataStoragePlugin.java +12 -3
- package/dist/capacitor.d.ts.map +1 -1
- package/dist/capacitor.js +4 -3
- package/dist/core/Strata.d.ts +133 -2
- package/dist/core/Strata.d.ts.map +1 -1
- package/dist/core/Strata.js +133 -2
- package/dist/firebase.d.ts.map +1 -1
- package/dist/firebase.js +21 -1
- package/dist/ios/Plugin/KeychainStorage.swift +31 -9
- package/dist/ios/Plugin/SQLiteStorage.swift +29 -6
- package/dist/ios/Plugin/UserDefaultsStorage.swift +25 -7
- package/dist/package.json +5 -5
- package/dist/plugin/web.d.ts +10 -6
- package/dist/plugin/web.d.ts.map +1 -1
- package/dist/plugin/web.js +42 -13
- package/dist/utils/index.d.ts +0 -3
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +0 -3
- package/ios/Plugin/KeychainStorage.swift +31 -9
- package/ios/Plugin/SQLiteStorage.swift +29 -6
- package/ios/Plugin/UserDefaultsStorage.swift +25 -7
- package/package.json +15 -15
- package/dist/README.md +0 -179
|
@@ -137,23 +137,46 @@ import SQLite3
|
|
|
137
137
|
return result
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
@objc public func clear() -> Bool {
|
|
141
|
-
let deleteSQL
|
|
140
|
+
@objc public func clear(prefix: String? = nil) -> Bool {
|
|
141
|
+
let deleteSQL: String
|
|
142
|
+
if let prefix = prefix {
|
|
143
|
+
deleteSQL = "DELETE FROM \(tableName) WHERE key LIKE ?"
|
|
144
|
+
} else {
|
|
145
|
+
deleteSQL = "DELETE FROM \(tableName)"
|
|
146
|
+
}
|
|
147
|
+
|
|
142
148
|
var statement: OpaquePointer?
|
|
149
|
+
var result = sqlite3_prepare_v2(db, deleteSQL, -1, &statement, nil) == SQLITE_OK
|
|
143
150
|
|
|
144
|
-
|
|
145
|
-
|
|
151
|
+
if result && prefix != nil {
|
|
152
|
+
result = sqlite3_bind_text(statement, 1, "\(prefix!)%", -1, nil) == SQLITE_OK
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if result {
|
|
156
|
+
result = sqlite3_step(statement) == SQLITE_DONE
|
|
157
|
+
}
|
|
146
158
|
|
|
147
159
|
sqlite3_finalize(statement)
|
|
148
160
|
return result
|
|
149
161
|
}
|
|
150
162
|
|
|
151
|
-
@objc public func keys() -> [String] {
|
|
152
|
-
let querySQL
|
|
163
|
+
@objc public func keys(pattern: String? = nil) -> [String] {
|
|
164
|
+
let querySQL: String
|
|
165
|
+
if let pattern = pattern {
|
|
166
|
+
querySQL = "SELECT key FROM \(tableName) WHERE key LIKE ?"
|
|
167
|
+
} else {
|
|
168
|
+
querySQL = "SELECT key FROM \(tableName)"
|
|
169
|
+
}
|
|
170
|
+
|
|
153
171
|
var statement: OpaquePointer?
|
|
154
172
|
var keys: [String] = []
|
|
155
173
|
|
|
156
174
|
if sqlite3_prepare_v2(db, querySQL, -1, &statement, nil) == SQLITE_OK {
|
|
175
|
+
if let pattern = pattern {
|
|
176
|
+
// Use % wildcard for SQL LIKE pattern matching
|
|
177
|
+
sqlite3_bind_text(statement, 1, "%\(pattern)%", -1, nil)
|
|
178
|
+
}
|
|
179
|
+
|
|
157
180
|
while sqlite3_step(statement) == SQLITE_ROW {
|
|
158
181
|
if let key = sqlite3_column_text(statement, 0) {
|
|
159
182
|
keys.append(String(cString: key))
|
|
@@ -24,18 +24,36 @@ import Foundation
|
|
|
24
24
|
return userDefaults.synchronize()
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
@objc public func clear() -> Bool {
|
|
28
|
-
if let
|
|
29
|
-
|
|
27
|
+
@objc public func clear(prefix: String? = nil) -> Bool {
|
|
28
|
+
if let prefix = prefix {
|
|
29
|
+
// Clear only keys with the given prefix
|
|
30
|
+
let keysToRemove = keys(pattern: prefix)
|
|
31
|
+
for key in keysToRemove {
|
|
32
|
+
userDefaults.removeObject(forKey: key)
|
|
33
|
+
}
|
|
30
34
|
} else {
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
// Clear all keys
|
|
36
|
+
if let suiteName = suiteName {
|
|
37
|
+
UserDefaults(suiteName: suiteName)?.removePersistentDomain(forName: suiteName)
|
|
38
|
+
} else {
|
|
39
|
+
let domain = Bundle.main.bundleIdentifier!
|
|
40
|
+
userDefaults.removePersistentDomain(forName: domain)
|
|
41
|
+
}
|
|
33
42
|
}
|
|
34
43
|
return userDefaults.synchronize()
|
|
35
44
|
}
|
|
36
45
|
|
|
37
|
-
@objc public func keys() -> [String] {
|
|
38
|
-
|
|
46
|
+
@objc public func keys(pattern: String? = nil) -> [String] {
|
|
47
|
+
let allKeys = Array(userDefaults.dictionaryRepresentation().keys)
|
|
48
|
+
|
|
49
|
+
guard let pattern = pattern else {
|
|
50
|
+
return allKeys
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Filter keys by pattern (simple prefix matching)
|
|
54
|
+
return allKeys.filter { key in
|
|
55
|
+
key.hasPrefix(pattern) || key.contains(pattern)
|
|
56
|
+
}
|
|
39
57
|
}
|
|
40
58
|
|
|
41
59
|
@objc public func has(key: String) -> Bool {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strata-storage",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "Zero-dependency universal storage plugin providing a unified API for all storage operations across web, Android, and iOS platforms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"homepage": "https://github.com/aoneahsan/strata-storage#readme",
|
|
70
70
|
"dependencies": {},
|
|
71
71
|
"peerDependencies": {
|
|
72
|
-
"@angular/core": ">=
|
|
73
|
-
"@capacitor/core": "
|
|
74
|
-
"react": ">=
|
|
75
|
-
"vue": ">=3.
|
|
72
|
+
"@angular/core": ">=20.3.0",
|
|
73
|
+
"@capacitor/core": ">=7.4.0",
|
|
74
|
+
"react": ">=19.1.0",
|
|
75
|
+
"vue": ">=3.6.0"
|
|
76
76
|
},
|
|
77
77
|
"peerDependenciesMeta": {
|
|
78
78
|
"@capacitor/core": {
|
|
@@ -90,22 +90,22 @@
|
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@eslint/js": "^10.0.0",
|
|
93
|
-
"@types/node": "^24.
|
|
94
|
-
"@types/react": "^19.1.
|
|
95
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
96
|
-
"@typescript-eslint/parser": "^8.
|
|
93
|
+
"@types/node": "^24.6.0",
|
|
94
|
+
"@types/react": "^19.1.16",
|
|
95
|
+
"@typescript-eslint/eslint-plugin": "^8.45.0",
|
|
96
|
+
"@typescript-eslint/parser": "^8.45.0",
|
|
97
97
|
"@vitest/coverage-v8": "^3.2.4",
|
|
98
|
-
"eslint": "^9.
|
|
98
|
+
"eslint": "^9.36.0",
|
|
99
99
|
"eslint-config-prettier": "^10.1.8",
|
|
100
|
-
"eslint-plugin-prettier": "^5.5.
|
|
101
|
-
"jsdom": "^
|
|
100
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
101
|
+
"jsdom": "^27.0.0",
|
|
102
102
|
"prettier": "^3.6.2",
|
|
103
|
-
"typescript": "^5.
|
|
104
|
-
"typescript-eslint": "^8.
|
|
103
|
+
"typescript": "^5.7.2",
|
|
104
|
+
"typescript-eslint": "^8.45.0",
|
|
105
105
|
"vitest": "^3.2.4"
|
|
106
106
|
},
|
|
107
107
|
"engines": {
|
|
108
|
-
"node": ">=
|
|
108
|
+
"node": ">=24.2.0"
|
|
109
109
|
},
|
|
110
110
|
"capacitor": {
|
|
111
111
|
"ios": {
|
package/dist/README.md
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
# Strata Storage
|
|
2
|
-
|
|
3
|
-
## 📚 Documentation
|
|
4
|
-
|
|
5
|
-
- **[Getting Started](./docs/getting-started/installation.md)** - Installation and setup
|
|
6
|
-
- **[Quick Start Guide](./docs/getting-started/quick-start.md)** - Get running in minutes
|
|
7
|
-
- **[API Reference](./docs/api/README.md)** - Complete API documentation
|
|
8
|
-
- **[Configuration](./docs/getting-started/configuration.md)** - Configuration options
|
|
9
|
-
- **[Platform Guides](./docs/guides/platforms/web.md)** - Platform-specific guides
|
|
10
|
-
- **[Examples](./docs/examples/README.md)** - Code examples and recipes
|
|
11
|
-
- **[GitHub](https://github.com/aoneahsan/strata-storage)** - Source code
|
|
12
|
-
- **[NPM](https://www.npmjs.com/package/strata-storage)** - Package registry
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
**One API. Every Storage. Everywhere.**
|
|
17
|
-
|
|
18
|
-
Zero-dependency universal storage plugin providing a unified API for all storage operations across web, Android, and iOS platforms.
|
|
19
|
-
|
|
20
|
-
## 🚀 Quick Start
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npm install strata-storage
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
### Provider-less Usage (Zero Setup)
|
|
27
|
-
```typescript
|
|
28
|
-
import { storage } from 'strata-storage';
|
|
29
|
-
|
|
30
|
-
// Works immediately - no setup, no providers, no initialization!
|
|
31
|
-
await storage.set('user', { name: 'John', age: 30 });
|
|
32
|
-
const user = await storage.get('user');
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Complete Example App
|
|
36
|
-
|
|
37
|
-
Check out our [React + Capacitor example app](./examples/react-capacitor-app) that demonstrates all features:
|
|
38
|
-
- All storage adapters working correctly
|
|
39
|
-
- Web, Android, and iOS platform support
|
|
40
|
-
- Real-time testing interface
|
|
41
|
-
- Complete error handling
|
|
42
|
-
|
|
43
|
-
Run the example:
|
|
44
|
-
```bash
|
|
45
|
-
cd examples/react-capacitor-app
|
|
46
|
-
yarn install
|
|
47
|
-
yarn start # For web
|
|
48
|
-
npx cap run android # For Android
|
|
49
|
-
npx cap run ios # For iOS
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### With Capacitor (Optional)
|
|
53
|
-
```typescript
|
|
54
|
-
import { storage } from 'strata-storage';
|
|
55
|
-
import { registerCapacitorAdapters } from 'strata-storage/capacitor';
|
|
56
|
-
|
|
57
|
-
// Only if you need native features
|
|
58
|
-
if (window.Capacitor) {
|
|
59
|
-
await registerCapacitorAdapters(storage);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Use native storage when available
|
|
63
|
-
await storage.set('secure-data', 'secret', { storage: 'secure' });
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### With Firebase (Optional)
|
|
67
|
-
```typescript
|
|
68
|
-
import { storage } from 'strata-storage';
|
|
69
|
-
import { enableFirebaseSync } from 'strata-storage/firebase';
|
|
70
|
-
|
|
71
|
-
// Only if you need cloud sync
|
|
72
|
-
if (needCloudSync) {
|
|
73
|
-
await enableFirebaseSync(storage, {
|
|
74
|
-
apiKey: 'your-api-key',
|
|
75
|
-
projectId: 'your-project-id',
|
|
76
|
-
firestore: true
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Works offline-first, syncs when online
|
|
81
|
-
await storage.set('data', value, { storage: 'firestore' });
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## ✨ Features
|
|
85
|
-
|
|
86
|
-
### Core Features
|
|
87
|
-
- ✅ **Zero Dependencies** - No runtime dependencies, pure implementation
|
|
88
|
-
- ✅ **Provider-less Architecture** - No providers, contexts, or wrappers needed (like zustand)
|
|
89
|
-
- ✅ **Works Everywhere** - React, Vue, Angular, Vanilla JS, Node.js - same API
|
|
90
|
-
- ✅ **Zero Configuration** - Import and use immediately, no setup required
|
|
91
|
-
- ✅ **Opt-in Complexity** - Start simple, add features only when needed
|
|
92
|
-
- ✅ **Dynamic Provider Loading** - Providers load only when used, keeping bundle small
|
|
93
|
-
- ✅ **Universal API** - Single interface for all storage types
|
|
94
|
-
- ✅ **Cross-Platform** - Web, iOS, Android support
|
|
95
|
-
- ✅ **TypeScript** - Full type safety and IntelliSense
|
|
96
|
-
- ✅ **Auto Fallback** - Intelligent storage selection
|
|
97
|
-
|
|
98
|
-
### Storage Adapters
|
|
99
|
-
- ✅ **Memory** - Fast in-memory storage
|
|
100
|
-
- ✅ **LocalStorage** - Persistent browser storage
|
|
101
|
-
- ✅ **SessionStorage** - Session-based browser storage
|
|
102
|
-
- ✅ **IndexedDB** - Large-scale browser database
|
|
103
|
-
- ✅ **Cookies** - HTTP cookie storage
|
|
104
|
-
- ✅ **Cache API** - Service worker cache storage
|
|
105
|
-
- ✅ **Capacitor Preferences** - Native mobile preferences
|
|
106
|
-
- ✅ **SQLite** - Mobile SQL database
|
|
107
|
-
- ✅ **Secure Storage** - Keychain (iOS) / Encrypted SharedPreferences (Android)
|
|
108
|
-
- ✅ **Filesystem** - File-based storage
|
|
109
|
-
|
|
110
|
-
### Advanced Features
|
|
111
|
-
- ✅ **Encryption** - AES-GCM encryption with Web Crypto API
|
|
112
|
-
- ✅ **Compression** - LZ-string compression algorithm
|
|
113
|
-
- ✅ **Cross-Tab Sync** - Real-time synchronization across tabs
|
|
114
|
-
- ✅ **Query Engine** - MongoDB-like queries for filtering data
|
|
115
|
-
- ✅ **TTL Support** - Automatic expiration with sliding TTL
|
|
116
|
-
- ✅ **Migration System** - Version-based data migrations
|
|
117
|
-
- 🚧 **Framework Integrations** - React, Vue, Angular (coming soon)
|
|
118
|
-
|
|
119
|
-
## 📖 Basic Usage
|
|
120
|
-
|
|
121
|
-
```typescript
|
|
122
|
-
import { storage } from 'strata-storage';
|
|
123
|
-
|
|
124
|
-
// No initialization needed - works immediately!
|
|
125
|
-
|
|
126
|
-
// Simple usage
|
|
127
|
-
await storage.set('key', 'value');
|
|
128
|
-
const value = await storage.get('key');
|
|
129
|
-
await storage.remove('key');
|
|
130
|
-
await storage.clear();
|
|
131
|
-
|
|
132
|
-
// Advanced options
|
|
133
|
-
await storage.set('key', value, {
|
|
134
|
-
storage: 'indexedDB', // Choose specific storage
|
|
135
|
-
ttl: 3600000, // Expire in 1 hour
|
|
136
|
-
encrypt: true, // Encrypt this value
|
|
137
|
-
compress: true, // Compress if beneficial
|
|
138
|
-
tags: ['user-data'] // Tag for grouping
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// Query data
|
|
142
|
-
const results = await storage.query({
|
|
143
|
-
tags: { $in: ['user-data'] },
|
|
144
|
-
'value.age': { $gte: 18 }
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// Subscribe to changes
|
|
148
|
-
storage.subscribe((change) => {
|
|
149
|
-
console.log(`${change.key} changed from ${change.oldValue} to ${change.newValue}`);
|
|
150
|
-
});
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
## 🎯 Provider-less Architecture
|
|
154
|
-
|
|
155
|
-
Strata Storage follows a provider-less architecture similar to Zustand. The core library works everywhere with zero dependencies, and platform-specific features (like Capacitor) are completely optional.
|
|
156
|
-
|
|
157
|
-
- **Minimal by default** - Only includes web storage adapters
|
|
158
|
-
- **Opt-in native features** - Explicitly add Capacitor support when needed
|
|
159
|
-
- **Better tree-shaking** - Unused adapters are eliminated by bundlers
|
|
160
|
-
- **Smaller bundle size** - Web-only projects don't include native code
|
|
161
|
-
|
|
162
|
-
## 🏗 Project Status
|
|
163
|
-
|
|
164
|
-
Currently in active development. Phase 1-5 completed:
|
|
165
|
-
- ✅ Project setup and core architecture
|
|
166
|
-
- ✅ Memory and web storage adapters
|
|
167
|
-
- ✅ Capacitor plugin structure (now optional)
|
|
168
|
-
- ✅ Advanced features (encryption, compression, sync, query, TTL)
|
|
169
|
-
- ✅ Provider-less architecture
|
|
170
|
-
- 🚧 Native implementations (iOS/Android)
|
|
171
|
-
- 🚧 Testing and documentation
|
|
172
|
-
|
|
173
|
-
## 📄 License
|
|
174
|
-
|
|
175
|
-
MIT
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
Created by Ahsan Mahmood
|