@pigeonmal/react-native-nitro-fetch 0.2.0 → 0.2.1

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/NitroFetch.podspec +30 -30
  2. package/android/CMakeLists.txt +70 -70
  3. package/android/build.gradle +128 -127
  4. package/android/cronet-release/build.gradle +2 -2
  5. package/android/gradle.properties +5 -5
  6. package/android/src/main/AndroidManifest.xml +2 -2
  7. package/android/src/main/cpp/cpp-adapter.cpp +6 -6
  8. package/android/src/main/java/com/margelo/nitro/nitrofetch/AutoPrefetcher.kt +72 -72
  9. package/android/src/main/java/com/margelo/nitro/nitrofetch/FetchCache.kt +57 -57
  10. package/android/src/main/java/com/margelo/nitro/nitrofetch/NativeStorage.kt +102 -102
  11. package/android/src/main/java/com/margelo/nitro/nitrofetch/NitroFetch.kt +95 -95
  12. package/android/src/main/java/com/margelo/nitro/nitrofetch/NitroFetchClient.kt +317 -317
  13. package/android/src/main/java/com/margelo/nitro/nitrofetch/NitroFetchPackage.kt +22 -22
  14. package/ios/FetchCache.swift +56 -56
  15. package/ios/NativeStorage.swift +61 -61
  16. package/ios/NitroAutoPrefetcher.swift +45 -45
  17. package/ios/NitroBootstrap.mm +27 -27
  18. package/ios/NitroFetch.swift +9 -9
  19. package/ios/NitroFetchClient.swift +230 -230
  20. package/lib/module/NitroFetch.nitro.js.map +1 -1
  21. package/lib/module/NitroInstances.js.map +1 -1
  22. package/lib/module/fetch.js.map +1 -1
  23. package/lib/module/index.js.map +1 -1
  24. package/lib/module/type.js.map +1 -1
  25. package/nitro.json +25 -25
  26. package/package.json +163 -162
  27. package/src/NitroFetch.nitro.ts +67 -67
  28. package/src/NitroInstances.ts +14 -14
  29. package/src/fetch.ts +603 -603
  30. package/src/index.tsx +17 -17
  31. package/src/type.ts +3 -3
@@ -1,30 +1,30 @@
1
- require "json"
2
-
3
- package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
-
5
- Pod::Spec.new do |s|
6
- s.name = "NitroFetch"
7
- s.version = package["version"]
8
- s.summary = package["description"]
9
- s.homepage = package["homepage"]
10
- s.license = package["license"]
11
- s.authors = package["author"]
12
-
13
- s.platforms = { :ios => min_ios_version_supported }
14
- s.source = { :git => "http://google.com.git", :tag => "#{s.version}" }
15
-
16
-
17
- s.source_files = [
18
- "ios/**/*.{swift}",
19
- "ios/**/*.{m,mm}",
20
- "cpp/**/*.{hpp,cpp}",
21
- ]
22
-
23
- s.dependency 'React-jsi'
24
- s.dependency 'React-callinvoker'
25
-
26
- load 'nitrogen/generated/ios/NitroFetch+autolinking.rb'
27
- add_nitrogen_files(s)
28
-
29
- install_modules_dependencies(s)
30
- end
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "NitroFetch"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.platforms = { :ios => min_ios_version_supported }
14
+ s.source = { :git => "http://google.com.git", :tag => "#{s.version}" }
15
+
16
+
17
+ s.source_files = [
18
+ "ios/**/*.{swift}",
19
+ "ios/**/*.{m,mm}",
20
+ "cpp/**/*.{hpp,cpp}",
21
+ ]
22
+
23
+ s.dependency 'React-jsi'
24
+ s.dependency 'React-callinvoker'
25
+
26
+ load 'nitrogen/generated/ios/NitroFetch+autolinking.rb'
27
+ add_nitrogen_files(s)
28
+
29
+ install_modules_dependencies(s)
30
+ end
@@ -1,70 +1,70 @@
1
- project(nitrofetch)
2
- cmake_minimum_required(VERSION 3.9.0)
3
-
4
- set(PACKAGE_NAME nitrofetch)
5
- set(CMAKE_VERBOSE_MAKEFILE ON)
6
- set(CMAKE_CXX_STANDARD 20)
7
-
8
- # Define C++ library and add all sources
9
- add_library(${PACKAGE_NAME} SHARED
10
- src/main/cpp/cpp-adapter.cpp
11
- )
12
-
13
- # Add Nitrogen specs :)
14
- include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/nitrofetch+autolinking.cmake)
15
-
16
- # Set up local includes
17
- include_directories("src/main/cpp" "../cpp")
18
-
19
- # Allow Gradle to pass a CRONET_ROOT pointing to extracted headers/libs (see build.gradle prepareCronet task)
20
- if (DEFINED CRONET_ROOT)
21
- set(CRONET_ROOT_DIR ${CRONET_ROOT})
22
- else()
23
- set(CRONET_ROOT_DIR ${CMAKE_SOURCE_DIR}/cronet)
24
- endif()
25
-
26
- # Optional: include Cronet headers if present (placed by script under android/cronet/include)
27
- if (EXISTS ${CRONET_ROOT_DIR}/include)
28
- message(STATUS "Cronet headers base: ${CRONET_ROOT_DIR}/include")
29
- include_directories(${CRONET_ROOT_DIR}/include)
30
- # Some Cronet packages nest headers under include/cronet
31
- if (EXISTS ${CRONET_ROOT_DIR}/include/cronet)
32
- include_directories(${CRONET_ROOT_DIR}/include/cronet)
33
- if (EXISTS ${CRONET_ROOT_DIR}/include/cronet/cronet_c.h)
34
- message(STATUS "Found cronet_c.h: ${CRONET_ROOT_DIR}/include/cronet/cronet_c.h")
35
- else()
36
- message(WARNING "cronet_c.h not found under ${CRONET_ROOT_DIR}/include/cronet")
37
- endif()
38
- if (EXISTS ${CRONET_ROOT_DIR}/include/cronet/cronet.idl_c.h)
39
- message(STATUS "Found cronet.idl_c.h: ${CRONET_ROOT_DIR}/include/cronet/cronet.idl_c.h")
40
- else()
41
- message(WARNING "cronet.idl_c.h not found under ${CRONET_ROOT_DIR}/include/cronet")
42
- endif()
43
- else()
44
- message(WARNING "Cronet nested include dir not found: ${CRONET_ROOT_DIR}/include/cronet")
45
- endif()
46
- endif()
47
-
48
- find_library(LOG_LIB log)
49
-
50
- # Link all libraries together
51
- target_link_libraries(
52
- ${PACKAGE_NAME}
53
- ${LOG_LIB}
54
- android # <-- Android core
55
- )
56
-
57
- ## Kotlin-based implementation only; no custom C++ headers forced.
58
-
59
- # Optional: link Cronet if library file is present (drop-in via prepare script or Gradle task)
60
- set(CRONET_LIB_DIR ${CRONET_ROOT_DIR}/libs/${ANDROID_ABI})
61
- if (EXISTS ${CRONET_LIB_DIR})
62
- file(GLOB CRONET_LIBS "${CRONET_LIB_DIR}/*cronet*.so")
63
- if (CRONET_LIBS)
64
- message(STATUS "Linking Cronet from ${CRONET_LIB_DIR}")
65
- target_link_libraries(${PACKAGE_NAME} ${CRONET_LIBS})
66
- target_compile_definitions(${PACKAGE_NAME} PRIVATE NITROFETCH_LINKS_CRONET=1)
67
- else()
68
- message(WARNING "Cronet libs not found in ${CRONET_LIB_DIR}")
69
- endif()
70
- endif()
1
+ project(nitrofetch)
2
+ cmake_minimum_required(VERSION 3.9.0)
3
+
4
+ set(PACKAGE_NAME nitrofetch)
5
+ set(CMAKE_VERBOSE_MAKEFILE ON)
6
+ set(CMAKE_CXX_STANDARD 20)
7
+
8
+ # Define C++ library and add all sources
9
+ add_library(${PACKAGE_NAME} SHARED
10
+ src/main/cpp/cpp-adapter.cpp
11
+ )
12
+
13
+ # Add Nitrogen specs :)
14
+ include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/nitrofetch+autolinking.cmake)
15
+
16
+ # Set up local includes
17
+ include_directories("src/main/cpp" "../cpp")
18
+
19
+ # Allow Gradle to pass a CRONET_ROOT pointing to extracted headers/libs (see build.gradle prepareCronet task)
20
+ if (DEFINED CRONET_ROOT)
21
+ set(CRONET_ROOT_DIR ${CRONET_ROOT})
22
+ else()
23
+ set(CRONET_ROOT_DIR ${CMAKE_SOURCE_DIR}/cronet)
24
+ endif()
25
+
26
+ # Optional: include Cronet headers if present (placed by script under android/cronet/include)
27
+ if (EXISTS ${CRONET_ROOT_DIR}/include)
28
+ message(STATUS "Cronet headers base: ${CRONET_ROOT_DIR}/include")
29
+ include_directories(${CRONET_ROOT_DIR}/include)
30
+ # Some Cronet packages nest headers under include/cronet
31
+ if (EXISTS ${CRONET_ROOT_DIR}/include/cronet)
32
+ include_directories(${CRONET_ROOT_DIR}/include/cronet)
33
+ if (EXISTS ${CRONET_ROOT_DIR}/include/cronet/cronet_c.h)
34
+ message(STATUS "Found cronet_c.h: ${CRONET_ROOT_DIR}/include/cronet/cronet_c.h")
35
+ else()
36
+ message(WARNING "cronet_c.h not found under ${CRONET_ROOT_DIR}/include/cronet")
37
+ endif()
38
+ if (EXISTS ${CRONET_ROOT_DIR}/include/cronet/cronet.idl_c.h)
39
+ message(STATUS "Found cronet.idl_c.h: ${CRONET_ROOT_DIR}/include/cronet/cronet.idl_c.h")
40
+ else()
41
+ message(WARNING "cronet.idl_c.h not found under ${CRONET_ROOT_DIR}/include/cronet")
42
+ endif()
43
+ else()
44
+ message(WARNING "Cronet nested include dir not found: ${CRONET_ROOT_DIR}/include/cronet")
45
+ endif()
46
+ endif()
47
+
48
+ find_library(LOG_LIB log)
49
+
50
+ # Link all libraries together
51
+ target_link_libraries(
52
+ ${PACKAGE_NAME}
53
+ ${LOG_LIB}
54
+ android # <-- Android core
55
+ )
56
+
57
+ ## Kotlin-based implementation only; no custom C++ headers forced.
58
+
59
+ # Optional: link Cronet if library file is present (drop-in via prepare script or Gradle task)
60
+ set(CRONET_LIB_DIR ${CRONET_ROOT_DIR}/libs/${ANDROID_ABI})
61
+ if (EXISTS ${CRONET_LIB_DIR})
62
+ file(GLOB CRONET_LIBS "${CRONET_LIB_DIR}/*cronet*.so")
63
+ if (CRONET_LIBS)
64
+ message(STATUS "Linking Cronet from ${CRONET_LIB_DIR}")
65
+ target_link_libraries(${PACKAGE_NAME} ${CRONET_LIBS})
66
+ target_compile_definitions(${PACKAGE_NAME} PRIVATE NITROFETCH_LINKS_CRONET=1)
67
+ else()
68
+ message(WARNING "Cronet libs not found in ${CRONET_LIB_DIR}")
69
+ endif()
70
+ endif()
@@ -1,127 +1,128 @@
1
- buildscript {
2
- ext.getExtOrDefault = {name ->
3
- return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['NitroFetch_' + name]
4
- }
5
-
6
- repositories {
7
- google()
8
- mavenCentral()
9
- }
10
-
11
- dependencies {
12
- classpath "com.android.tools.build:gradle:8.7.2"
13
- // noinspection DifferentKotlinGradleVersion
14
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
15
- }
16
- }
17
-
18
- def reactNativeArchitectures() {
19
- def value = rootProject.getProperties().get("reactNativeArchitectures")
20
- return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
21
- }
22
-
23
- apply plugin: "com.android.library"
24
- apply plugin: "kotlin-android"
25
- apply from: '../nitrogen/generated/android/nitrofetch+autolinking.gradle'
26
-
27
- // Do not apply React Gradle plugin in library to avoid RN codegen duplicating app classes
28
-
29
- def getExtOrIntegerDefault(name) {
30
- return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["NitroFetch_" + name]).toInteger()
31
- }
32
-
33
- android {
34
- namespace "com.margelo.nitro.nitrofetch"
35
-
36
- compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
37
-
38
- defaultConfig {
39
- minSdkVersion getExtOrIntegerDefault("minSdkVersion")
40
- targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
41
-
42
- externalNativeBuild {
43
- cmake {
44
- cppFlags "-frtti -fexceptions -Wall -fstack-protector-all"
45
- arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
46
- abiFilters (*reactNativeArchitectures())
47
- }
48
- }
49
- }
50
-
51
- externalNativeBuild {
52
- cmake {
53
- path "CMakeLists.txt"
54
- }
55
- }
56
-
57
- packagingOptions {
58
- excludes = [
59
- "**/libc++_shared.so",
60
- "**/libfbjni.so",
61
- "**/libjsi.so",
62
- "**/libfolly_json.so",
63
- "**/libfolly_runtime.so",
64
- "**/libglog.so",
65
- "**/libhermes.so",
66
- "**/libhermes-executor-debug.so",
67
- "**/libhermes_executor.so",
68
- "**/libreactnative.so",
69
- "**/libreactnativejni.so",
70
- "**/libturbomodulejsijni.so",
71
- "**/libreact_nativemodule_core.so",
72
- "**/libjscexecutor.so"
73
- ]
74
- }
75
-
76
- buildFeatures {
77
- buildConfig true
78
- prefab true
79
- }
80
-
81
- buildTypes {
82
- release {
83
- minifyEnabled false
84
- }
85
- }
86
-
87
- lintOptions {
88
- disable "GradleCompatible"
89
- }
90
-
91
- compileOptions {
92
- sourceCompatibility JavaVersion.VERSION_1_8
93
- targetCompatibility JavaVersion.VERSION_1_8
94
- }
95
-
96
- sourceSets {
97
- main {
98
- java.srcDirs += [
99
- "generated/java",
100
- "generated/jni"
101
- ]
102
- }
103
- }
104
- }
105
-
106
- repositories {
107
- mavenCentral()
108
- google()
109
- }
110
-
111
- def kotlin_version = getExtOrDefault("kotlinVersion")
112
-
113
- dependencies {
114
- implementation "com.facebook.react:react-android"
115
- implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
116
- implementation project(":react-native-nitro-modules")
117
- api project(':cronet-release')
118
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0"
119
-
120
- }
121
-
122
- configurations {
123
- cronetAar
124
- }
125
-
126
-
127
- // No automatic fetching of Cronet headers/libs; library uses Cronet Java API only.
1
+ buildscript {
2
+ ext.getExtOrDefault = {name ->
3
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['NitroFetch_' + name]
4
+ }
5
+
6
+ repositories {
7
+ google()
8
+ mavenCentral()
9
+ }
10
+
11
+ dependencies {
12
+ classpath "com.android.tools.build:gradle:8.7.2"
13
+ // noinspection DifferentKotlinGradleVersion
14
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
15
+ }
16
+ }
17
+
18
+ def reactNativeArchitectures() {
19
+ def value = rootProject.getProperties().get("reactNativeArchitectures")
20
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
21
+ }
22
+
23
+ apply plugin: "com.android.library"
24
+ apply plugin: "kotlin-android"
25
+ apply from: '../nitrogen/generated/android/nitrofetch+autolinking.gradle'
26
+
27
+ // Do not apply React Gradle plugin in library to avoid RN codegen duplicating app classes
28
+
29
+ def getExtOrIntegerDefault(name) {
30
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["NitroFetch_" + name]).toInteger()
31
+ }
32
+
33
+ android {
34
+ namespace "com.margelo.nitro.nitrofetch"
35
+
36
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
37
+
38
+ defaultConfig {
39
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
40
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
41
+
42
+ externalNativeBuild {
43
+ cmake {
44
+ cppFlags "-frtti -fexceptions -Wall -fstack-protector-all"
45
+ arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
46
+ abiFilters (*reactNativeArchitectures())
47
+ }
48
+ }
49
+ }
50
+
51
+ externalNativeBuild {
52
+ cmake {
53
+ path "CMakeLists.txt"
54
+ }
55
+ }
56
+
57
+ packagingOptions {
58
+ excludes = [
59
+ "**/libc++_shared.so",
60
+ "**/libfbjni.so",
61
+ "**/libjsi.so",
62
+ "**/libfolly_json.so",
63
+ "**/libfolly_runtime.so",
64
+ "**/libglog.so",
65
+ "**/libhermes.so",
66
+ "**/libhermes-executor-debug.so",
67
+ "**/libhermes_executor.so",
68
+ "**/libreactnative.so",
69
+ "**/libreactnativejni.so",
70
+ "**/libturbomodulejsijni.so",
71
+ "**/libreact_nativemodule_core.so",
72
+ "**/libjscexecutor.so"
73
+ ]
74
+ }
75
+
76
+ buildFeatures {
77
+ buildConfig true
78
+ prefab true
79
+ }
80
+
81
+ buildTypes {
82
+ release {
83
+ minifyEnabled false
84
+ }
85
+ }
86
+
87
+ lintOptions {
88
+ disable "GradleCompatible"
89
+ }
90
+
91
+ compileOptions {
92
+ sourceCompatibility JavaVersion.VERSION_1_8
93
+ targetCompatibility JavaVersion.VERSION_1_8
94
+ }
95
+
96
+ sourceSets {
97
+ main {
98
+ java.srcDirs += [
99
+ "generated/java",
100
+ "generated/jni"
101
+ ]
102
+ }
103
+ }
104
+ }
105
+
106
+ repositories {
107
+ mavenCentral()
108
+ google()
109
+ }
110
+
111
+ def kotlin_version = getExtOrDefault("kotlinVersion")
112
+
113
+ dependencies {
114
+ implementation "com.facebook.react:react-android"
115
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
116
+ implementation project(":react-native-nitro-modules")
117
+ api project(':cronet-release')
118
+ implementation "com.google.protobuf:protobuf-javalite:3.25.8"
119
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0"
120
+
121
+ }
122
+
123
+ configurations {
124
+ cronetAar
125
+ }
126
+
127
+
128
+ // No automatic fetching of Cronet headers/libs; library uses Cronet Java API only.
@@ -1,2 +1,2 @@
1
- configurations.maybeCreate("default")
2
- artifacts.add("default", file('cronet-release.aar'))
1
+ configurations.maybeCreate("default")
2
+ artifacts.add("default", file('cronet-release.aar'))
@@ -1,5 +1,5 @@
1
- NitroFetch_kotlinVersion=2.0.21
2
- NitroFetch_minSdkVersion=24
3
- NitroFetch_targetSdkVersion=34
4
- NitroFetch_compileSdkVersion=35
5
- NitroFetch_ndkVersion=27.1.12297006
1
+ NitroFetch_kotlinVersion=2.0.21
2
+ NitroFetch_minSdkVersion=24
3
+ NitroFetch_targetSdkVersion=34
4
+ NitroFetch_compileSdkVersion=35
5
+ NitroFetch_ndkVersion=27.1.12297006
@@ -1,2 +1,2 @@
1
- <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
- </manifest>
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -1,6 +1,6 @@
1
- #include <jni.h>
2
- #include "nitrofetchOnLoad.hpp"
3
-
4
- JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
5
- return margelo::nitro::nitrofetch::initialize(vm);
6
- }
1
+ #include <jni.h>
2
+ #include "nitrofetchOnLoad.hpp"
3
+
4
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
5
+ return margelo::nitro::nitrofetch::initialize(vm);
6
+ }
@@ -1,72 +1,72 @@
1
- package com.margelo.nitro.nitrofetch
2
-
3
- import android.app.Application
4
- import android.content.Context
5
- import org.json.JSONArray
6
- import org.json.JSONObject
7
- import java.util.concurrent.CompletableFuture
8
-
9
-
10
- object AutoPrefetcher {
11
- @Volatile private var initialized = false
12
- private const val KEY_QUEUE = "nitrofetch_autoprefetch_queue"
13
- private const val PREFS_NAME = "nitro_fetch_storage"
14
-
15
- fun prefetchOnStart(app: Application) {
16
- if (initialized) return
17
- initialized = true
18
- try {
19
- val prefs = app.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
20
- val raw = prefs.getString(KEY_QUEUE, null) ?: ""
21
- if (raw.isEmpty()) return
22
- val arr = JSONArray(raw)
23
- for (i in 0 until arr.length()) {
24
- val o = arr.optJSONObject(i) ?: continue
25
- val url = o.optString("url", null) ?: continue
26
- val prefetchKey = o.optString("prefetchKey", null) ?: continue
27
- val headersObj = o.optJSONObject("headers") ?: JSONObject()
28
- val headersList = mutableListOf<Pair<String, String>>()
29
- headersObj.keys().forEachRemaining { k ->
30
- headersList.add(k to headersObj.optString(k, ""))
31
- }
32
- // Ensure prefetchKey header is present
33
- headersList.add("prefetchKey" to prefetchKey)
34
-
35
- val headerObjs = headersList.map { (k, v) -> NitroHeader(k, v) }.toTypedArray()
36
- val req = NitroRequest(
37
- url = url,
38
- method = null,
39
- headers = headerObjs,
40
- bodyString = null,
41
- bodyBytes = null,
42
- timeoutMs = null,
43
- followRedirects = null
44
- )
45
-
46
- // If already pending or fresh, skip starting a new one
47
- if (FetchCache.getPending(prefetchKey) != null) continue
48
- if (FetchCache.hasFreshResult(prefetchKey, 5_000L)) continue
49
-
50
- val future = CompletableFuture<NitroResponse>()
51
- FetchCache.setPending(prefetchKey, future)
52
- NitroFetchClient.fetch(req,
53
- onSuccess = { res ->
54
- try {
55
- FetchCache.complete(prefetchKey, res)
56
- future.complete(res)
57
- } catch (t: Throwable) {
58
- FetchCache.completeExceptionally(prefetchKey, t)
59
- future.completeExceptionally(t)
60
- }
61
- },
62
- onFail = { err ->
63
- FetchCache.completeExceptionally(prefetchKey, err)
64
- future.completeExceptionally(err)
65
- }
66
- )
67
- }
68
- } catch (_: Throwable) {
69
- // ignore – prefetch-on-start is best-effort
70
- }
71
- }
72
- }
1
+ package com.margelo.nitro.nitrofetch
2
+
3
+ import android.app.Application
4
+ import android.content.Context
5
+ import org.json.JSONArray
6
+ import org.json.JSONObject
7
+ import java.util.concurrent.CompletableFuture
8
+
9
+
10
+ object AutoPrefetcher {
11
+ @Volatile private var initialized = false
12
+ private const val KEY_QUEUE = "nitrofetch_autoprefetch_queue"
13
+ private const val PREFS_NAME = "nitro_fetch_storage"
14
+
15
+ fun prefetchOnStart(app: Application) {
16
+ if (initialized) return
17
+ initialized = true
18
+ try {
19
+ val prefs = app.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
20
+ val raw = prefs.getString(KEY_QUEUE, null) ?: ""
21
+ if (raw.isEmpty()) return
22
+ val arr = JSONArray(raw)
23
+ for (i in 0 until arr.length()) {
24
+ val o = arr.optJSONObject(i) ?: continue
25
+ val url = o.optString("url", null) ?: continue
26
+ val prefetchKey = o.optString("prefetchKey", null) ?: continue
27
+ val headersObj = o.optJSONObject("headers") ?: JSONObject()
28
+ val headersList = mutableListOf<Pair<String, String>>()
29
+ headersObj.keys().forEachRemaining { k ->
30
+ headersList.add(k to headersObj.optString(k, ""))
31
+ }
32
+ // Ensure prefetchKey header is present
33
+ headersList.add("prefetchKey" to prefetchKey)
34
+
35
+ val headerObjs = headersList.map { (k, v) -> NitroHeader(k, v) }.toTypedArray()
36
+ val req = NitroRequest(
37
+ url = url,
38
+ method = null,
39
+ headers = headerObjs,
40
+ bodyString = null,
41
+ bodyBytes = null,
42
+ timeoutMs = null,
43
+ followRedirects = null
44
+ )
45
+
46
+ // If already pending or fresh, skip starting a new one
47
+ if (FetchCache.getPending(prefetchKey) != null) continue
48
+ if (FetchCache.hasFreshResult(prefetchKey, 5_000L)) continue
49
+
50
+ val future = CompletableFuture<NitroResponse>()
51
+ FetchCache.setPending(prefetchKey, future)
52
+ NitroFetchClient.fetch(req,
53
+ onSuccess = { res ->
54
+ try {
55
+ FetchCache.complete(prefetchKey, res)
56
+ future.complete(res)
57
+ } catch (t: Throwable) {
58
+ FetchCache.completeExceptionally(prefetchKey, t)
59
+ future.completeExceptionally(t)
60
+ }
61
+ },
62
+ onFail = { err ->
63
+ FetchCache.completeExceptionally(prefetchKey, err)
64
+ future.completeExceptionally(err)
65
+ }
66
+ )
67
+ }
68
+ } catch (_: Throwable) {
69
+ // ignore – prefetch-on-start is best-effort
70
+ }
71
+ }
72
+ }