react-native-nitro-storage 0.3.0 → 0.3.2

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 (53) hide show
  1. package/README.md +594 -247
  2. package/android/CMakeLists.txt +2 -0
  3. package/android/src/main/cpp/AndroidStorageAdapterCpp.cpp +102 -11
  4. package/android/src/main/cpp/AndroidStorageAdapterCpp.hpp +16 -0
  5. package/android/src/main/java/com/nitrostorage/AndroidStorageAdapter.kt +154 -34
  6. package/android/src/main/java/com/nitrostorage/NitroStoragePackage.kt +2 -2
  7. package/cpp/bindings/HybridStorage.cpp +176 -21
  8. package/cpp/bindings/HybridStorage.hpp +29 -2
  9. package/cpp/core/NativeStorageAdapter.hpp +16 -0
  10. package/ios/IOSStorageAdapterCpp.hpp +20 -0
  11. package/ios/IOSStorageAdapterCpp.mm +239 -32
  12. package/lib/commonjs/Storage.types.js +23 -1
  13. package/lib/commonjs/Storage.types.js.map +1 -1
  14. package/lib/commonjs/index.js +292 -75
  15. package/lib/commonjs/index.js.map +1 -1
  16. package/lib/commonjs/index.web.js +473 -86
  17. package/lib/commonjs/index.web.js.map +1 -1
  18. package/lib/commonjs/internal.js +10 -0
  19. package/lib/commonjs/internal.js.map +1 -1
  20. package/lib/commonjs/storage-hooks.js +36 -0
  21. package/lib/commonjs/storage-hooks.js.map +1 -0
  22. package/lib/module/Storage.types.js +22 -0
  23. package/lib/module/Storage.types.js.map +1 -1
  24. package/lib/module/index.js +264 -75
  25. package/lib/module/index.js.map +1 -1
  26. package/lib/module/index.web.js +445 -86
  27. package/lib/module/index.web.js.map +1 -1
  28. package/lib/module/internal.js +8 -0
  29. package/lib/module/internal.js.map +1 -1
  30. package/lib/module/storage-hooks.js +30 -0
  31. package/lib/module/storage-hooks.js.map +1 -0
  32. package/lib/typescript/Storage.nitro.d.ts +12 -0
  33. package/lib/typescript/Storage.nitro.d.ts.map +1 -1
  34. package/lib/typescript/Storage.types.d.ts +20 -0
  35. package/lib/typescript/Storage.types.d.ts.map +1 -1
  36. package/lib/typescript/index.d.ts +33 -10
  37. package/lib/typescript/index.d.ts.map +1 -1
  38. package/lib/typescript/index.web.d.ts +45 -10
  39. package/lib/typescript/index.web.d.ts.map +1 -1
  40. package/lib/typescript/internal.d.ts +2 -0
  41. package/lib/typescript/internal.d.ts.map +1 -1
  42. package/lib/typescript/storage-hooks.d.ts +10 -0
  43. package/lib/typescript/storage-hooks.d.ts.map +1 -0
  44. package/nitrogen/generated/shared/c++/HybridStorageSpec.cpp +12 -0
  45. package/nitrogen/generated/shared/c++/HybridStorageSpec.hpp +12 -0
  46. package/package.json +8 -3
  47. package/src/Storage.nitro.ts +13 -2
  48. package/src/Storage.types.ts +22 -0
  49. package/src/index.ts +382 -123
  50. package/src/index.web.ts +618 -134
  51. package/src/internal.ts +14 -4
  52. package/src/migration.ts +1 -1
  53. package/src/storage-hooks.ts +48 -0
package/src/internal.ts CHANGED
@@ -4,6 +4,7 @@ export const MIGRATION_VERSION_KEY = "__nitro_storage_migration_version__";
4
4
  export const NATIVE_BATCH_MISSING_SENTINEL =
5
5
  "__nitro_storage_batch_missing__::v1";
6
6
  const PRIMITIVE_FAST_PATH_PREFIX = "__nitro_storage_primitive__:";
7
+ const NAMESPACE_SEPARATOR = ":";
7
8
 
8
9
  export type StoredEnvelope = {
9
10
  __nitroStorageEnvelope: true;
@@ -41,7 +42,7 @@ export type ScopedBatchItem = {
41
42
 
42
43
  export function assertBatchScope(
43
44
  items: readonly ScopedBatchItem[],
44
- scope: StorageScope
45
+ scope: StorageScope,
45
46
  ): void {
46
47
  const mismatchedItem = items.find((item) => item.scope !== scope);
47
48
  if (!mismatchedItem) {
@@ -53,12 +54,12 @@ export function assertBatchScope(
53
54
  StorageScope[mismatchedItem.scope] ?? String(mismatchedItem.scope);
54
55
 
55
56
  throw new Error(
56
- `Batch scope mismatch for "${mismatchedItem.key}": expected ${expectedScope}, received ${actualScope}.`
57
+ `Batch scope mismatch for "${mismatchedItem.key}": expected ${expectedScope}, received ${actualScope}.`,
57
58
  );
58
59
  }
59
60
 
60
61
  export function decodeNativeBatchValue(
61
- value: string | undefined
62
+ value: string | undefined,
62
63
  ): string | undefined {
63
64
  if (value === NATIVE_BATCH_MISSING_SENTINEL) {
64
65
  return undefined;
@@ -67,6 +68,15 @@ export function decodeNativeBatchValue(
67
68
  return value;
68
69
  }
69
70
 
71
+ export function prefixKey(namespace: string | undefined, key: string): string {
72
+ if (!namespace) return key;
73
+ return `${namespace}${NAMESPACE_SEPARATOR}${key}`;
74
+ }
75
+
76
+ export function isNamespaced(key: string, namespace: string): boolean {
77
+ return key.startsWith(`${namespace}${NAMESPACE_SEPARATOR}`);
78
+ }
79
+
70
80
  export function serializeWithPrimitiveFastPath<T>(value: T): string {
71
81
  if (value === null) {
72
82
  return `${PRIMITIVE_FAST_PATH_PREFIX}l`;
@@ -91,7 +101,7 @@ export function serializeWithPrimitiveFastPath<T>(value: T): string {
91
101
  const serialized = JSON.stringify(value);
92
102
  if (serialized === undefined) {
93
103
  throw new Error(
94
- "Unable to serialize value with default serializer. Provide a custom serialize function."
104
+ "Unable to serialize value with default serializer. Provide a custom serialize function.",
95
105
  );
96
106
  }
97
107
  return serialized;
package/src/migration.ts CHANGED
@@ -12,7 +12,7 @@ export type MMKVLike = {
12
12
  export function migrateFromMMKV<T>(
13
13
  mmkv: MMKVLike,
14
14
  item: StorageItem<T>,
15
- deleteFromMMKV = false
15
+ deleteFromMMKV = false,
16
16
  ): boolean {
17
17
  const key = item.key;
18
18
  if (!mmkv.contains(key)) {
@@ -0,0 +1,48 @@
1
+ import { useRef, useSyncExternalStore } from "react";
2
+
3
+ type HookStorageItem<T> = {
4
+ get: () => T;
5
+ set: (value: T | ((prev: T) => T)) => void;
6
+ subscribe: (callback: () => void) => () => void;
7
+ };
8
+
9
+ export function useStorage<T>(
10
+ item: HookStorageItem<T>,
11
+ ): [T, (value: T | ((prev: T) => T)) => void] {
12
+ const value = useSyncExternalStore(item.subscribe, item.get, item.get);
13
+ return [value, item.set];
14
+ }
15
+
16
+ export function useStorageSelector<T, TSelected>(
17
+ item: HookStorageItem<T>,
18
+ selector: (value: T) => TSelected,
19
+ isEqual: (prev: TSelected, next: TSelected) => boolean = Object.is,
20
+ ): [TSelected, (value: T | ((prev: T) => T)) => void] {
21
+ const selectedRef = useRef<
22
+ { hasValue: false } | { hasValue: true; value: TSelected }
23
+ >({
24
+ hasValue: false,
25
+ });
26
+
27
+ const getSelectedSnapshot = () => {
28
+ const nextSelected = selector(item.get());
29
+ const current = selectedRef.current;
30
+ if (current.hasValue && isEqual(current.value, nextSelected)) {
31
+ return current.value;
32
+ }
33
+
34
+ selectedRef.current = { hasValue: true, value: nextSelected };
35
+ return nextSelected;
36
+ };
37
+
38
+ const selectedValue = useSyncExternalStore(
39
+ item.subscribe,
40
+ getSelectedSnapshot,
41
+ getSelectedSnapshot,
42
+ );
43
+ return [selectedValue, item.set];
44
+ }
45
+
46
+ export function useSetStorage<T>(item: HookStorageItem<T>) {
47
+ return item.set;
48
+ }