strata-storage 2.0.3 → 2.1.0

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 (31) hide show
  1. package/Readme.md +109 -27
  2. package/android/src/main/java/com/strata/storage/EncryptedStorage.java +44 -3
  3. package/android/src/main/java/com/strata/storage/SQLiteStorage.java +35 -5
  4. package/android/src/main/java/com/strata/storage/SharedPreferencesStorage.java +43 -3
  5. package/android/src/main/java/com/stratastorage/StrataStoragePlugin.java +12 -3
  6. package/dist/android/src/main/java/com/strata/storage/EncryptedStorage.java +44 -3
  7. package/dist/android/src/main/java/com/strata/storage/SQLiteStorage.java +35 -5
  8. package/dist/android/src/main/java/com/strata/storage/SharedPreferencesStorage.java +43 -3
  9. package/dist/android/src/main/java/com/stratastorage/StrataStoragePlugin.java +12 -3
  10. package/dist/capacitor.d.ts.map +1 -1
  11. package/dist/capacitor.js +4 -3
  12. package/dist/core/Strata.d.ts +133 -2
  13. package/dist/core/Strata.d.ts.map +1 -1
  14. package/dist/core/Strata.js +133 -2
  15. package/dist/firebase.d.ts.map +1 -1
  16. package/dist/firebase.js +21 -1
  17. package/dist/ios/Plugin/KeychainStorage.swift +31 -9
  18. package/dist/ios/Plugin/SQLiteStorage.swift +29 -6
  19. package/dist/ios/Plugin/UserDefaultsStorage.swift +25 -7
  20. package/dist/package.json +5 -5
  21. package/dist/plugin/web.d.ts +10 -6
  22. package/dist/plugin/web.d.ts.map +1 -1
  23. package/dist/plugin/web.js +42 -13
  24. package/dist/utils/index.d.ts +0 -3
  25. package/dist/utils/index.d.ts.map +1 -1
  26. package/dist/utils/index.js +0 -3
  27. package/ios/Plugin/KeychainStorage.swift +31 -9
  28. package/ios/Plugin/SQLiteStorage.swift +29 -6
  29. package/ios/Plugin/UserDefaultsStorage.swift +25 -7
  30. package/package.json +15 -15
  31. package/dist/README.md +0 -179
@@ -6,30 +6,59 @@ export class StrataStorageWeb {
6
6
  async isAvailable(_options) {
7
7
  // Web platform doesn't support native storage types
8
8
  // This is handled by the web adapters instead
9
- return { available: false };
9
+ return {
10
+ available: false,
11
+ platform: 'web',
12
+ message: 'Native storage not available on web. Use web adapters: localStorage, sessionStorage, indexedDB, cookies, or cache instead.',
13
+ };
10
14
  }
11
- async get(_options) {
15
+ async get(options) {
12
16
  // Not implemented for web - use web adapters instead
13
- throw new Error('Native storage not available on web platform');
17
+ const storageType = options.storage || 'preferences';
18
+ const suggestion = this.getSuggestion(storageType);
19
+ throw new Error(`Native storage '${storageType}' not available on web platform. ${suggestion}`);
14
20
  }
15
- async set(_options) {
21
+ async set(options) {
16
22
  // Not implemented for web - use web adapters instead
17
- throw new Error('Native storage not available on web platform');
23
+ const storageType = options.storage || 'preferences';
24
+ const suggestion = this.getSuggestion(storageType);
25
+ throw new Error(`Native storage '${storageType}' not available on web platform. ${suggestion}`);
18
26
  }
19
- async remove(_options) {
27
+ async remove(options) {
20
28
  // Not implemented for web - use web adapters instead
21
- throw new Error('Native storage not available on web platform');
29
+ const storageType = options.storage || 'preferences';
30
+ const suggestion = this.getSuggestion(storageType);
31
+ throw new Error(`Native storage '${storageType}' not available on web platform. ${suggestion}`);
22
32
  }
23
- async clear(_options) {
33
+ async clear(options) {
24
34
  // Not implemented for web - use web adapters instead
25
- throw new Error('Native storage not available on web platform');
35
+ const storageType = options.storage || 'preferences';
36
+ const suggestion = this.getSuggestion(storageType);
37
+ throw new Error(`Native storage '${storageType}' not available on web platform. ${suggestion}`);
26
38
  }
27
- async keys(_options) {
39
+ async keys(options) {
28
40
  // Not implemented for web - use web adapters instead
29
- throw new Error('Native storage not available on web platform');
41
+ const storageType = options.storage || 'preferences';
42
+ const suggestion = this.getSuggestion(storageType);
43
+ throw new Error(`Native storage '${storageType}' not available on web platform. ${suggestion}`);
30
44
  }
31
- async size(_options) {
45
+ async size(options) {
32
46
  // Not implemented for web - use web adapters instead
33
- throw new Error('Native storage not available on web platform');
47
+ const storageType = options.storage || 'preferences';
48
+ const suggestion = this.getSuggestion(storageType);
49
+ throw new Error(`Native storage '${storageType}' not available on web platform. ${suggestion}`);
50
+ }
51
+ /**
52
+ * Get suggestion for web alternative based on native storage type
53
+ */
54
+ getSuggestion(storageType) {
55
+ const suggestions = {
56
+ preferences: 'Use localStorage adapter for persistent key-value storage.',
57
+ secure: 'Use indexedDB adapter with encryption enabled for secure storage.',
58
+ sqlite: 'Use indexedDB adapter for database-like storage.',
59
+ filesystem: 'Use Cache API adapter or indexedDB for file storage.',
60
+ };
61
+ return (suggestions[storageType] ||
62
+ 'Use one of the web adapters: localStorage, sessionStorage, indexedDB, cookies, or cache.');
34
63
  }
35
64
  }
@@ -118,8 +118,5 @@ export declare function serializeValue(value: unknown): string;
118
118
  * Deserialize a value from storage
119
119
  */
120
120
  export declare function deserializeValue(value: string): unknown;
121
- /**
122
- * Create an error with additional context
123
- */
124
121
  export declare function createError(message: string, code?: string, details?: unknown): Error;
125
122
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
@@ -352,9 +352,6 @@ export function serializeValue(value) {
352
352
  export function deserializeValue(value) {
353
353
  return deserialize(value);
354
354
  }
355
- /**
356
- * Create an error with additional context
357
- */
358
355
  export function createError(message, code, details) {
359
356
  const error = new Error(message);
360
357
  error.code = code;
@@ -40,16 +40,29 @@ import Security
40
40
  return status == errSecSuccess
41
41
  }
42
42
 
43
- @objc public func clear() -> Bool {
44
- let query: [String: Any] = [
45
- kSecClass as String: kSecClassGenericPassword,
46
- kSecAttrService as String: service
47
- ]
48
- let status = SecItemDelete(query as CFDictionary)
49
- return status == errSecSuccess || status == errSecItemNotFound
43
+ @objc public func clear(prefix: String? = nil) -> Bool {
44
+ if let prefix = prefix {
45
+ // Clear only keys with the given prefix
46
+ let keysToRemove = keys(pattern: prefix)
47
+ var allSuccess = true
48
+ for key in keysToRemove {
49
+ if !remove(key: key) {
50
+ allSuccess = false
51
+ }
52
+ }
53
+ return allSuccess
54
+ } else {
55
+ // Clear all keys
56
+ let query: [String: Any] = [
57
+ kSecClass as String: kSecClassGenericPassword,
58
+ kSecAttrService as String: service
59
+ ]
60
+ let status = SecItemDelete(query as CFDictionary)
61
+ return status == errSecSuccess || status == errSecItemNotFound
62
+ }
50
63
  }
51
64
 
52
- @objc public func keys() -> [String] {
65
+ @objc public func keys(pattern: String? = nil) -> [String] {
53
66
  var query: [String: Any] = [
54
67
  kSecClass as String: kSecClassGenericPassword,
55
68
  kSecAttrService as String: service,
@@ -67,7 +80,16 @@ import Security
67
80
  guard status == errSecSuccess,
68
81
  let items = result as? [[String: Any]] else { return [] }
69
82
 
70
- return items.compactMap { $0[kSecAttrAccount as String] as? String }
83
+ let allKeys = items.compactMap { $0[kSecAttrAccount as String] as? String }
84
+
85
+ guard let pattern = pattern else {
86
+ return allKeys
87
+ }
88
+
89
+ // Filter keys by pattern (simple prefix matching)
90
+ return allKeys.filter { key in
91
+ key.hasPrefix(pattern) || key.contains(pattern)
92
+ }
71
93
  }
72
94
 
73
95
  private func createQuery(key: String) -> [String: Any] {
@@ -137,23 +137,46 @@ import SQLite3
137
137
  return result
138
138
  }
139
139
 
140
- @objc public func clear() -> Bool {
141
- let deleteSQL = "DELETE FROM \(tableName)"
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
- let result = sqlite3_prepare_v2(db, deleteSQL, -1, &statement, nil) == SQLITE_OK &&
145
- sqlite3_step(statement) == SQLITE_DONE
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 = "SELECT key FROM \(tableName)"
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 suiteName = suiteName {
29
- UserDefaults(suiteName: suiteName)?.removePersistentDomain(forName: suiteName)
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
- let domain = Bundle.main.bundleIdentifier!
32
- userDefaults.removePersistentDomain(forName: domain)
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
- return Array(userDefaults.dictionaryRepresentation().keys)
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",
3
+ "version": "2.1.0",
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": ">=12.0.0",
73
- "@capacitor/core": "^5.0.0 || ^6.0.0",
74
- "react": ">=16.8.0",
75
- "vue": ">=3.0.0"
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.2.0",
94
- "@types/react": "^19.1.9",
95
- "@typescript-eslint/eslint-plugin": "^8.39.0",
96
- "@typescript-eslint/parser": "^8.39.0",
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.32.0",
98
+ "eslint": "^9.36.0",
99
99
  "eslint-config-prettier": "^10.1.8",
100
- "eslint-plugin-prettier": "^5.5.3",
101
- "jsdom": "^26.1.0",
100
+ "eslint-plugin-prettier": "^5.5.4",
101
+ "jsdom": "^27.0.0",
102
102
  "prettier": "^3.6.2",
103
- "typescript": "^5.9.2",
104
- "typescript-eslint": "^8.39.0",
103
+ "typescript": "^5.7.2",
104
+ "typescript-eslint": "^8.45.0",
105
105
  "vitest": "^3.2.4"
106
106
  },
107
107
  "engines": {
108
- "node": ">=18.0.0"
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