@kafitra/lynx-storage 0.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.
- package/README.md +196 -0
- package/android/build/.transforms/57b45319aa48ed838ae9c1d47b5c9e46/results.bin +1 -0
- package/android/build/.transforms/57b45319aa48ed838ae9c1d47b5c9e46/transformed/debug/com/kafitra/lynxstorage/LynxStorageModule.dex +0 -0
- package/android/build/.transforms/57b45319aa48ed838ae9c1d47b5c9e46/transformed/debug/desugar_graph.bin +0 -0
- package/android/build/.transforms/8b0ebf77b1668e7a22dbb51308dd3b00/results.bin +1 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml +7 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json +18 -0
- package/android/build/intermediates/aar_metadata/debug/aar-metadata.properties +5 -0
- package/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json +1 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/R.txt +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
- package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +2 -0
- package/android/build/intermediates/javac/debug/classes/com/kafitra/lynxstorage/LynxStorageModule.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/R-def.txt +2 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt +7 -0
- package/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml +7 -0
- package/android/build/intermediates/navigation_json/debug/navigation.json +1 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/kafitra/lynxstorage/LynxStorageModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt +1 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +16 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build.gradle +21 -0
- package/android/src/main/java/com/kafitra/lynxstorage/LynxStorageModule.java +115 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/native.d.ts +8 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +10 -0
- package/dist/native.js.map +1 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/ios/LynxStorageModule.h +20 -0
- package/ios/LynxStorageModule.m +102 -0
- package/lynx.module.json +7 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# @kafitra/lynx-storage
|
|
4
|
+
|
|
5
|
+
**Persistent key-value storage native module for [Lynx](https://lynxjs.org/).**
|
|
6
|
+
|
|
7
|
+
Backed by **Android SharedPreferences** and **iOS NSUserDefaults** — data survives app restarts.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@kafitra/lynx-storage)
|
|
10
|
+
[]()
|
|
11
|
+
[](../../LICENSE)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
`@kafitra/lynx-storage` exposes a synchronous native key-value store to the Lynx JS runtime via `NativeModules.LynxStorage`. It is the persistence layer used by [`@kafitra/lynx-async-storage`](../lynx-async-storage) when running inside a Lynx app.
|
|
20
|
+
|
|
21
|
+
| Platform | Implementation | Storage file / suite |
|
|
22
|
+
| -------- | ------------------- | ------------------------- |
|
|
23
|
+
| Android | `SharedPreferences` | `kafitra_lynx_storage` |
|
|
24
|
+
| iOS | `NSUserDefaults` | `com.kafitra.lynxstorage` |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @kafitra/lynx-storage
|
|
32
|
+
# or
|
|
33
|
+
pnpm add @kafitra/lynx-storage
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Android Setup
|
|
39
|
+
|
|
40
|
+
### 1. Auto-link (recommended)
|
|
41
|
+
|
|
42
|
+
Run the Kafitra CLI linker from your app directory:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx @kafitra/lynx-cli link
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This auto-generates `LynxAutolinkRegistry.java` and injects Gradle wiring.
|
|
49
|
+
|
|
50
|
+
### 2. Register in your Application class
|
|
51
|
+
|
|
52
|
+
```java
|
|
53
|
+
// LynxApplication.java (or wherever you init LynxEnv)
|
|
54
|
+
import com.kafitra.demo.LynxAutolinkRegistry;
|
|
55
|
+
|
|
56
|
+
LynxEnv.inst().init(this, null, null, null);
|
|
57
|
+
LynxAutolinkRegistry.registerAll(); // ← registers LynxStorageModule
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. Manual setup (without CLI)
|
|
61
|
+
|
|
62
|
+
If you prefer not to use the CLI, add these entries manually:
|
|
63
|
+
|
|
64
|
+
**`android/settings.gradle`**
|
|
65
|
+
|
|
66
|
+
```groovy
|
|
67
|
+
include ':lynx-storage'
|
|
68
|
+
project(':lynx-storage').projectDir = new File(rootDir, '../node_modules/@kafitra/lynx-storage/android')
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**`android/app/build.gradle`**
|
|
72
|
+
|
|
73
|
+
```groovy
|
|
74
|
+
dependencies {
|
|
75
|
+
implementation project(':lynx-storage')
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**`LynxAutolinkRegistry.java`** (or your Application init)
|
|
80
|
+
|
|
81
|
+
```java
|
|
82
|
+
import com.kafitra.lynxstorage.LynxStorageModule;
|
|
83
|
+
|
|
84
|
+
LynxEnv.inst().registerModule("LynxStorage", LynxStorageModule.class);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## iOS Setup
|
|
90
|
+
|
|
91
|
+
### Register in your host app
|
|
92
|
+
|
|
93
|
+
```objc
|
|
94
|
+
// In your LynxInitProcessor or AppDelegate, before creating any Lynx view:
|
|
95
|
+
#import "LynxStorageModule.h"
|
|
96
|
+
|
|
97
|
+
[globalConfig registerModule:LynxStorageModule.class];
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## JavaScript API
|
|
103
|
+
|
|
104
|
+
The module is exposed on the Lynx `NativeModules` global as `NativeModules.LynxStorage`:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
declare const NativeModules: {
|
|
108
|
+
LynxStorage: {
|
|
109
|
+
getString(key: string): string | null;
|
|
110
|
+
setString(key: string, value: string): void;
|
|
111
|
+
remove(key: string): void;
|
|
112
|
+
clear(): void;
|
|
113
|
+
getAllKeys(): string; // JSON array string, e.g. '["a","b"]'
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Direct usage (TypeScript)
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { LynxStorage } from "@kafitra/lynx-storage";
|
|
122
|
+
|
|
123
|
+
// Read
|
|
124
|
+
const value = LynxStorage.getString("token"); // string | null
|
|
125
|
+
|
|
126
|
+
// Write
|
|
127
|
+
LynxStorage.setString("token", "abc123");
|
|
128
|
+
|
|
129
|
+
// Delete
|
|
130
|
+
LynxStorage.remove("token");
|
|
131
|
+
|
|
132
|
+
// Clear everything
|
|
133
|
+
LynxStorage.clear();
|
|
134
|
+
|
|
135
|
+
// Get all keys
|
|
136
|
+
const keys = JSON.parse(LynxStorage.getAllKeys()); // string[]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
> **Tip:** All methods are **synchronous**. If you prefer a Promise-based API, use [`@kafitra/lynx-async-storage`](https://www.npmjs.com/package/@kafitra/lynx-async-storage) — it auto-detects and wraps this module.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## With @kafitra/lynx-async-storage
|
|
144
|
+
|
|
145
|
+
Install both packages in your app:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
pnpm add @kafitra/lynx-storage @kafitra/lynx-async-storage
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Then use `@kafitra/lynx-async-storage` in your code — it will automatically use `LynxStorage` as its backend:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
import AsyncStorage from "@kafitra/lynx-async-storage";
|
|
155
|
+
|
|
156
|
+
await AsyncStorage.setItem("session", JSON.stringify({ user: "demo" }));
|
|
157
|
+
const session = await AsyncStorage.getItem("session");
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
No extra configuration needed. `@kafitra/lynx-async-storage` detects `NativeModules.LynxStorage` at runtime and uses it automatically.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## `lynx.module.json`
|
|
165
|
+
|
|
166
|
+
This file is used by `@kafitra/lynx-autolink` for auto-linking:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"name": "LynxStorage",
|
|
171
|
+
"android": {
|
|
172
|
+
"moduleClass": "com.kafitra.lynxstorage.LynxStorageModule",
|
|
173
|
+
"sourceDir": "android"
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Monorepo / Workspace
|
|
181
|
+
|
|
182
|
+
If you're using this in a monorepo with `pnpm workspaces`:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"dependencies": {
|
|
187
|
+
"@kafitra/lynx-storage": "workspace:*"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
MIT © [Kafitra Marna](https://github.com/kafitramarna)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
o/debug
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
i/
|
package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"artifactType": {
|
|
4
|
+
"type": "AAPT_FRIENDLY_MERGED_MANIFESTS",
|
|
5
|
+
"kind": "Directory"
|
|
6
|
+
},
|
|
7
|
+
"applicationId": "com.kafitra.lynxstorage",
|
|
8
|
+
"variantName": "debug",
|
|
9
|
+
"elements": [
|
|
10
|
+
{
|
|
11
|
+
"type": "SINGLE",
|
|
12
|
+
"filters": [],
|
|
13
|
+
"attributes": [],
|
|
14
|
+
"outputFile": "AndroidManifest.xml"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"elementType": "File"
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
Binary file
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#Sat Feb 21 11:39:55 WIB 2026
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<merger version="3"><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\src\main\res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main" generated-set="main$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\src\main\res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\src\debug\res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug" generated-set="debug$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\src\debug\res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\generated\res\resValues\debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated" generated-set="generated$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\generated\res\resValues\debug"/></dataSet><mergedItems/></merger>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\src\main\jniLibs"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\src\debug\jniLibs"/></dataSet></merger>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\src\main\shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\src\debug\shaders"/></dataSet></merger>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\src\main\assets"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\src\debug\assets"/></dataSet><dataSet config="generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\intermediates\shader_assets\debug\out"/></dataSet></merger>
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[]
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
com.kafitra.lynxstorage
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
-- Merging decision tree log ---
|
|
2
|
+
manifest
|
|
3
|
+
ADDED from C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\intermediates\tmp\ProcessLibraryManifest\debug\tempAndroidManifest15751414143782047258.xml:2:13-83
|
|
4
|
+
INJECTED from C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\intermediates\tmp\ProcessLibraryManifest\debug\tempAndroidManifest15751414143782047258.xml:2:13-83
|
|
5
|
+
package
|
|
6
|
+
INJECTED from C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\intermediates\tmp\ProcessLibraryManifest\debug\tempAndroidManifest15751414143782047258.xml
|
|
7
|
+
xmlns:android
|
|
8
|
+
ADDED from C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\intermediates\tmp\ProcessLibraryManifest\debug\tempAndroidManifest15751414143782047258.xml:2:23-81
|
|
9
|
+
uses-sdk
|
|
10
|
+
INJECTED from C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\intermediates\tmp\ProcessLibraryManifest\debug\tempAndroidManifest15751414143782047258.xml reason: use-sdk injection requested
|
|
11
|
+
INJECTED from C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\intermediates\tmp\ProcessLibraryManifest\debug\tempAndroidManifest15751414143782047258.xml
|
|
12
|
+
INJECTED from C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\intermediates\tmp\ProcessLibraryManifest\debug\tempAndroidManifest15751414143782047258.xml
|
|
13
|
+
android:targetSdkVersion
|
|
14
|
+
INJECTED from C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\intermediates\tmp\ProcessLibraryManifest\debug\tempAndroidManifest15751414143782047258.xml
|
|
15
|
+
android:minSdkVersion
|
|
16
|
+
INJECTED from C:\Users\HYPE AMD\Documents\Coding\lynx\kafitra-lynx-native\apps\demo2\node_modules\@kafitra\lynx-storage\android\build\intermediates\tmp\ProcessLibraryManifest\debug\tempAndroidManifest15751414143782047258.xml
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
apply plugin: 'com.android.library'
|
|
2
|
+
|
|
3
|
+
android {
|
|
4
|
+
namespace 'com.kafitra.lynxstorage'
|
|
5
|
+
compileSdkVersion 34
|
|
6
|
+
|
|
7
|
+
defaultConfig {
|
|
8
|
+
minSdkVersion 21
|
|
9
|
+
targetSdkVersion 34
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
compileOptions {
|
|
13
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
14
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
dependencies {
|
|
19
|
+
// Provided at runtime by the host app — compileOnly to avoid duplicate classes
|
|
20
|
+
compileOnly "org.lynxsdk.lynx:lynx:3.6.0"
|
|
21
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
package com.kafitra.lynxstorage;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.content.SharedPreferences;
|
|
5
|
+
|
|
6
|
+
import com.lynx.jsbridge.LynxModule;
|
|
7
|
+
import com.lynx.jsbridge.LynxMethod;
|
|
8
|
+
|
|
9
|
+
import org.json.JSONArray;
|
|
10
|
+
|
|
11
|
+
import java.util.Map;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* LynxStorageModule — persistent key-value storage backed by SharedPreferences.
|
|
15
|
+
*
|
|
16
|
+
* Provides synchronous access to Android SharedPreferences through the
|
|
17
|
+
* Lynx Native Module system.
|
|
18
|
+
*
|
|
19
|
+
* <h3>Registration (in your host app):</h3>
|
|
20
|
+
* <pre>
|
|
21
|
+
* LynxEnv.inst().registerModule("LynxStorage", LynxStorageModule.class);
|
|
22
|
+
* </pre>
|
|
23
|
+
*
|
|
24
|
+
* <p>All values are stored as Strings under the shared preferences file
|
|
25
|
+
* {@code kafitra_lynx_storage}.</p>
|
|
26
|
+
*/
|
|
27
|
+
public class LynxStorageModule extends LynxModule {
|
|
28
|
+
|
|
29
|
+
private static final String PREFS_NAME = "kafitra_lynx_storage";
|
|
30
|
+
private final Context mContext;
|
|
31
|
+
|
|
32
|
+
public LynxStorageModule(Context context) {
|
|
33
|
+
super(context);
|
|
34
|
+
this.mContext = context;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private SharedPreferences prefs() {
|
|
38
|
+
return mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns the string stored under {@code key}, or {@code null} when absent.
|
|
43
|
+
*
|
|
44
|
+
* @param key Storage key
|
|
45
|
+
* @return Stored value or null
|
|
46
|
+
*/
|
|
47
|
+
@LynxMethod
|
|
48
|
+
public String getString(String key) {
|
|
49
|
+
try {
|
|
50
|
+
SharedPreferences sp = prefs();
|
|
51
|
+
if (!sp.contains(key)) return null;
|
|
52
|
+
return sp.getString(key, null);
|
|
53
|
+
} catch (Exception e) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Stores {@code value} under {@code key}.
|
|
60
|
+
*
|
|
61
|
+
* @param key Storage key
|
|
62
|
+
* @param value String value to persist
|
|
63
|
+
*/
|
|
64
|
+
@LynxMethod
|
|
65
|
+
public void setString(String key, String value) {
|
|
66
|
+
try {
|
|
67
|
+
prefs().edit().putString(key, value).apply();
|
|
68
|
+
} catch (Exception ignored) {
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Removes the entry for {@code key}. No-op when the key is absent.
|
|
74
|
+
*
|
|
75
|
+
* @param key Storage key to remove
|
|
76
|
+
*/
|
|
77
|
+
@LynxMethod
|
|
78
|
+
public void remove(String key) {
|
|
79
|
+
try {
|
|
80
|
+
prefs().edit().remove(key).apply();
|
|
81
|
+
} catch (Exception ignored) {
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Removes all entries from the storage namespace.
|
|
87
|
+
*/
|
|
88
|
+
@LynxMethod
|
|
89
|
+
public void clear() {
|
|
90
|
+
try {
|
|
91
|
+
prefs().edit().clear().apply();
|
|
92
|
+
} catch (Exception ignored) {
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Returns a JSON array string of all stored keys, e.g. {@code ["a","b","c"]}.
|
|
98
|
+
* Returns {@code "[]"} when storage is empty.
|
|
99
|
+
*
|
|
100
|
+
* @return JSON-encoded string array
|
|
101
|
+
*/
|
|
102
|
+
@LynxMethod
|
|
103
|
+
public String getAllKeys() {
|
|
104
|
+
try {
|
|
105
|
+
Map<String, ?> all = prefs().getAll();
|
|
106
|
+
JSONArray arr = new JSONArray();
|
|
107
|
+
for (String key : all.keySet()) {
|
|
108
|
+
arr.put(key);
|
|
109
|
+
}
|
|
110
|
+
return arr.toString();
|
|
111
|
+
} catch (Exception e) {
|
|
112
|
+
return "[]";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @kafitra/lynx-storage
|
|
3
|
+
*
|
|
4
|
+
* Public API — thin wrappers that surfaced the raw native module.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
*
|
|
8
|
+
* import { LynxStorage } from '@kafitra/lynx-storage';
|
|
9
|
+
*
|
|
10
|
+
* LynxStorage.setString('key', 'value');
|
|
11
|
+
* const val = LynxStorage.getString('key'); // string | null
|
|
12
|
+
*/
|
|
13
|
+
export { NativeStorage as LynxStorage } from "./native";
|
|
14
|
+
export type { NativeLynxStorage } from "./types";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,aAAa,IAAI,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @kafitra/lynx-storage
|
|
3
|
+
*
|
|
4
|
+
* Public API — thin wrappers that surfaced the raw native module.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
*
|
|
8
|
+
* import { LynxStorage } from '@kafitra/lynx-storage';
|
|
9
|
+
*
|
|
10
|
+
* LynxStorage.setString('key', 'value');
|
|
11
|
+
* const val = LynxStorage.getString('key'); // string | null
|
|
12
|
+
*/
|
|
13
|
+
export { NativeStorage as LynxStorage } from "./native";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,aAAa,IAAI,WAAW,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/native.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAiBjD,eAAO,MAAM,aAAa,EAAE,iBAAqC,CAAC"}
|
package/dist/native.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function getNativeModule() {
|
|
2
|
+
if (!NativeModules?.LynxStorage) {
|
|
3
|
+
throw new Error("[@kafitra/lynx-storage] Native module not linked. " +
|
|
4
|
+
"Register LynxStorageModule in your Android host:\n\n" +
|
|
5
|
+
' LynxEnv.inst().registerModule("LynxStorage", LynxStorageModule.class);');
|
|
6
|
+
}
|
|
7
|
+
return NativeModules.LynxStorage;
|
|
8
|
+
}
|
|
9
|
+
export const NativeStorage = getNativeModule();
|
|
10
|
+
//# sourceMappingURL=native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.js","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAWA,SAAS,eAAe;IACtB,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,oDAAoD;YAClD,sDAAsD;YACtD,0EAA0E,CAC7E,CAAC;IACJ,CAAC;IACD,OAAO,aAAa,CAAC,WAAW,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAsB,eAAe,EAAE,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @kafitra/lynx-storage
|
|
3
|
+
*
|
|
4
|
+
* Raw shape of the LynxStorage native module as exposed through
|
|
5
|
+
* NativeModules by the Lynx runtime.
|
|
6
|
+
*
|
|
7
|
+
* All methods are synchronous at the native layer.
|
|
8
|
+
*/
|
|
9
|
+
export interface NativeLynxStorage {
|
|
10
|
+
/** Returns the stored string, or null when absent. */
|
|
11
|
+
getString(key: string): string | null;
|
|
12
|
+
/** Stores a string value. */
|
|
13
|
+
setString(key: string, value: string): void;
|
|
14
|
+
/** Removes a single entry. */
|
|
15
|
+
remove(key: string): void;
|
|
16
|
+
/** Clears the entire storage namespace. */
|
|
17
|
+
clear(): void;
|
|
18
|
+
/** Returns all stored keys as a JSON array string, e.g. '["a","b"]'. */
|
|
19
|
+
getAllKeys(): string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,sDAAsD;IACtD,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAEtC,6BAA6B;IAC7B,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5C,8BAA8B;IAC9B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B,2CAA2C;IAC3C,KAAK,IAAI,IAAI,CAAC;IAEd,wEAAwE;IACxE,UAAU,IAAI,MAAM,CAAC;CACtB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @kafitra/lynx-storage
|
|
3
|
+
*
|
|
4
|
+
* iOS native module — persists key-value pairs in NSUserDefaults.
|
|
5
|
+
*
|
|
6
|
+
* Registration (in your LynxInitProcessor or app delegate):
|
|
7
|
+
*
|
|
8
|
+
* #import "LynxStorageModule.h"
|
|
9
|
+
* [globalConfig registerModule:LynxStorageModule.class];
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
#import <Foundation/Foundation.h>
|
|
13
|
+
#import <Lynx/LynxModule.h>
|
|
14
|
+
|
|
15
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
16
|
+
|
|
17
|
+
@interface LynxStorageModule : NSObject <LynxModule>
|
|
18
|
+
@end
|
|
19
|
+
|
|
20
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#import "LynxStorageModule.h"
|
|
2
|
+
|
|
3
|
+
// NSUserDefaults suite name – isolates keys from app defaults
|
|
4
|
+
static NSString *const kSuiteName = @"com.kafitra.lynxstorage";
|
|
5
|
+
|
|
6
|
+
@implementation LynxStorageModule
|
|
7
|
+
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Lynx module identity
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
+ (NSString *)name {
|
|
13
|
+
return @"LynxStorage";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Method lookup — maps JS method names to Objective-C selectors
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
+ (NSDictionary<NSString *, NSString *> *)methodLookup {
|
|
21
|
+
return @{
|
|
22
|
+
@"getString": NSStringFromSelector(@selector(getString:)),
|
|
23
|
+
@"setString": NSStringFromSelector(@selector(setString:value:)),
|
|
24
|
+
@"remove": NSStringFromSelector(@selector(remove:)),
|
|
25
|
+
@"clear": NSStringFromSelector(@selector(clear)),
|
|
26
|
+
@"getAllKeys": NSStringFromSelector(@selector(getAllKeys)),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Helpers
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
- (NSUserDefaults *)defaults {
|
|
35
|
+
NSUserDefaults *d = [[NSUserDefaults alloc] initWithSuiteName:kSuiteName];
|
|
36
|
+
return d ?: [NSUserDefaults standardUserDefaults];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Method implementations
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Returns the stored string for @p key, or nil when absent.
|
|
45
|
+
*/
|
|
46
|
+
- (nullable NSString *)getString:(NSString *)key {
|
|
47
|
+
@try {
|
|
48
|
+
return [[self defaults] stringForKey:key];
|
|
49
|
+
} @catch (NSException *e) {
|
|
50
|
+
return nil;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Persists @p value under @p key.
|
|
56
|
+
*/
|
|
57
|
+
- (void)setString:(NSString *)key value:(NSString *)value {
|
|
58
|
+
@try {
|
|
59
|
+
[[self defaults] setObject:value forKey:key];
|
|
60
|
+
[[self defaults] synchronize];
|
|
61
|
+
} @catch (NSException *e) { }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Removes the entry for @p key.
|
|
66
|
+
*/
|
|
67
|
+
- (void)remove:(NSString *)key {
|
|
68
|
+
@try {
|
|
69
|
+
[[self defaults] removeObjectForKey:key];
|
|
70
|
+
[[self defaults] synchronize];
|
|
71
|
+
} @catch (NSException *e) { }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Clears all keys in the kafitra.lynxstorage suite.
|
|
76
|
+
*/
|
|
77
|
+
- (void)clear {
|
|
78
|
+
@try {
|
|
79
|
+
NSDictionary *dict = [[self defaults] dictionaryRepresentation];
|
|
80
|
+
for (NSString *key in dict.allKeys) {
|
|
81
|
+
[[self defaults] removeObjectForKey:key];
|
|
82
|
+
}
|
|
83
|
+
[[self defaults] synchronize];
|
|
84
|
+
} @catch (NSException *e) { }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Returns a JSON-encoded array of all stored keys.
|
|
89
|
+
* e.g. ["session","theme","lang"]
|
|
90
|
+
*/
|
|
91
|
+
- (NSString *)getAllKeys {
|
|
92
|
+
@try {
|
|
93
|
+
NSDictionary *dict = [[self defaults] dictionaryRepresentation];
|
|
94
|
+
NSArray *keys = dict.allKeys;
|
|
95
|
+
NSData *data = [NSJSONSerialization dataWithJSONObject:keys options:0 error:nil];
|
|
96
|
+
return data ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : @"[]";
|
|
97
|
+
} @catch (NSException *e) {
|
|
98
|
+
return @"[]";
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@end
|
package/lynx.module.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kafitra/lynx-storage",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lynx Native Module for persistent key-value storage (Android SharedPreferences + iOS NSUserDefaults)",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"android",
|
|
10
|
+
"ios",
|
|
11
|
+
"lynx.module.json"
|
|
12
|
+
],
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"typescript": "^5.3.0",
|
|
15
|
+
"rimraf": "^5.0.0"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"lynx",
|
|
19
|
+
"native-module",
|
|
20
|
+
"storage",
|
|
21
|
+
"async-storage",
|
|
22
|
+
"android",
|
|
23
|
+
"ios"
|
|
24
|
+
],
|
|
25
|
+
"author": "Kafitra",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/kafitramarna/kafitra-lynx-native.git",
|
|
30
|
+
"directory": "packages/lynx-storage"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc",
|
|
40
|
+
"clean": "rimraf dist"
|
|
41
|
+
}
|
|
42
|
+
}
|