@tursodatabase/sync-react-native 0.5.0-pre.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.
Files changed (72) hide show
  1. package/README.md +117 -0
  2. package/android/CMakeLists.txt +53 -0
  3. package/android/build.gradle +84 -0
  4. package/android/cpp-adapter.cpp +49 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/com/turso/sync/reactnative/TursoBridge.java +44 -0
  7. package/android/src/main/java/com/turso/sync/reactnative/TursoModule.java +82 -0
  8. package/android/src/main/java/com/turso/sync/reactnative/TursoPackage.java +29 -0
  9. package/cpp/TursoConnectionHostObject.cpp +179 -0
  10. package/cpp/TursoConnectionHostObject.h +52 -0
  11. package/cpp/TursoDatabaseHostObject.cpp +98 -0
  12. package/cpp/TursoDatabaseHostObject.h +49 -0
  13. package/cpp/TursoHostObject.cpp +561 -0
  14. package/cpp/TursoHostObject.h +24 -0
  15. package/cpp/TursoStatementHostObject.cpp +414 -0
  16. package/cpp/TursoStatementHostObject.h +65 -0
  17. package/cpp/TursoSyncChangesHostObject.cpp +41 -0
  18. package/cpp/TursoSyncChangesHostObject.h +52 -0
  19. package/cpp/TursoSyncDatabaseHostObject.cpp +328 -0
  20. package/cpp/TursoSyncDatabaseHostObject.h +61 -0
  21. package/cpp/TursoSyncIoItemHostObject.cpp +304 -0
  22. package/cpp/TursoSyncIoItemHostObject.h +52 -0
  23. package/cpp/TursoSyncOperationHostObject.cpp +168 -0
  24. package/cpp/TursoSyncOperationHostObject.h +53 -0
  25. package/ios/TursoModule.h +8 -0
  26. package/ios/TursoModule.mm +95 -0
  27. package/lib/commonjs/Database.js +445 -0
  28. package/lib/commonjs/Database.js.map +1 -0
  29. package/lib/commonjs/Statement.js +339 -0
  30. package/lib/commonjs/Statement.js.map +1 -0
  31. package/lib/commonjs/index.js +229 -0
  32. package/lib/commonjs/index.js.map +1 -0
  33. package/lib/commonjs/internal/asyncOperation.js +124 -0
  34. package/lib/commonjs/internal/asyncOperation.js.map +1 -0
  35. package/lib/commonjs/internal/ioProcessor.js +315 -0
  36. package/lib/commonjs/internal/ioProcessor.js.map +1 -0
  37. package/lib/commonjs/package.json +1 -0
  38. package/lib/commonjs/types.js +133 -0
  39. package/lib/commonjs/types.js.map +1 -0
  40. package/lib/module/Database.js +441 -0
  41. package/lib/module/Database.js.map +1 -0
  42. package/lib/module/Statement.js +335 -0
  43. package/lib/module/Statement.js.map +1 -0
  44. package/lib/module/index.js +205 -0
  45. package/lib/module/index.js.map +1 -0
  46. package/lib/module/internal/asyncOperation.js +116 -0
  47. package/lib/module/internal/asyncOperation.js.map +1 -0
  48. package/lib/module/internal/ioProcessor.js +309 -0
  49. package/lib/module/internal/ioProcessor.js.map +1 -0
  50. package/lib/module/package.json +1 -0
  51. package/lib/module/types.js +163 -0
  52. package/lib/module/types.js.map +1 -0
  53. package/lib/typescript/Database.d.ts +140 -0
  54. package/lib/typescript/Database.d.ts.map +1 -0
  55. package/lib/typescript/Statement.d.ts +105 -0
  56. package/lib/typescript/Statement.d.ts.map +1 -0
  57. package/lib/typescript/index.d.ts +175 -0
  58. package/lib/typescript/index.d.ts.map +1 -0
  59. package/lib/typescript/internal/asyncOperation.d.ts +39 -0
  60. package/lib/typescript/internal/asyncOperation.d.ts.map +1 -0
  61. package/lib/typescript/internal/ioProcessor.d.ts +48 -0
  62. package/lib/typescript/internal/ioProcessor.d.ts.map +1 -0
  63. package/lib/typescript/types.d.ts +316 -0
  64. package/lib/typescript/types.d.ts.map +1 -0
  65. package/package.json +97 -0
  66. package/src/Database.ts +480 -0
  67. package/src/Statement.ts +372 -0
  68. package/src/index.ts +240 -0
  69. package/src/internal/asyncOperation.ts +147 -0
  70. package/src/internal/ioProcessor.ts +328 -0
  71. package/src/types.ts +391 -0
  72. package/turso-sync-react-native.podspec +56 -0
@@ -0,0 +1,52 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <memory>
5
+ #include <string>
6
+
7
+ // Forward declarations for Turso C API types
8
+ extern "C" {
9
+ struct turso_sync_io_item;
10
+ typedef struct turso_sync_io_item turso_sync_io_item_t;
11
+ }
12
+
13
+ namespace turso {
14
+
15
+ using namespace facebook;
16
+
17
+ /**
18
+ * TursoSyncIoItemHostObject wraps turso_sync_io_item_t* (IO queue item for fetch/fs operations).
19
+ * This is a THIN wrapper - 1:1 mapping of SDK-KIT C API with NO logic.
20
+ * All logic belongs in TypeScript or Rust, not here.
21
+ */
22
+ class TursoSyncIoItemHostObject : public jsi::HostObject {
23
+ public:
24
+ TursoSyncIoItemHostObject(turso_sync_io_item_t* item) : item_(item) {}
25
+ ~TursoSyncIoItemHostObject();
26
+
27
+ // JSI HostObject interface
28
+ jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &name) override;
29
+ void set(jsi::Runtime &rt, const jsi::PropNameID &name, const jsi::Value &value) override;
30
+ std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
31
+
32
+ // Direct access to wrapped pointer (for internal use)
33
+ turso_sync_io_item_t* getIoItem() const { return item_; }
34
+
35
+ private:
36
+ turso_sync_io_item_t* item_ = nullptr;
37
+
38
+ // Helper to throw JS errors
39
+ void throwError(jsi::Runtime &rt, const char *error);
40
+
41
+ // 1:1 C API mapping methods (NO logic - just calls through to C API)
42
+ jsi::Value getKind(jsi::Runtime &rt);
43
+ jsi::Value getHttpRequest(jsi::Runtime &rt);
44
+ jsi::Value getFullReadPath(jsi::Runtime &rt);
45
+ jsi::Value getFullWriteRequest(jsi::Runtime &rt);
46
+ jsi::Value poison(jsi::Runtime &rt, const jsi::Value *args, size_t count);
47
+ jsi::Value setStatus(jsi::Runtime &rt, const jsi::Value *args, size_t count);
48
+ jsi::Value pushBuffer(jsi::Runtime &rt, const jsi::Value *args, size_t count);
49
+ jsi::Value done(jsi::Runtime &rt);
50
+ };
51
+
52
+ } // namespace turso
@@ -0,0 +1,168 @@
1
+ #include "TursoSyncOperationHostObject.h"
2
+ #include "TursoConnectionHostObject.h"
3
+ #include "TursoSyncChangesHostObject.h"
4
+
5
+ extern "C" {
6
+ #include <turso_sync.h>
7
+ }
8
+
9
+ namespace turso {
10
+
11
+ TursoSyncOperationHostObject::~TursoSyncOperationHostObject() {
12
+ if (op_) {
13
+ turso_sync_operation_deinit(op_);
14
+ op_ = nullptr;
15
+ }
16
+ }
17
+
18
+ void TursoSyncOperationHostObject::throwError(jsi::Runtime &rt, const char *error) {
19
+ throw jsi::JSError(rt, error ? error : "Unknown error");
20
+ }
21
+
22
+ jsi::Value TursoSyncOperationHostObject::get(jsi::Runtime &rt, const jsi::PropNameID &name) {
23
+ auto propName = name.utf8(rt);
24
+
25
+ if (propName == "resume") {
26
+ return jsi::Function::createFromHostFunction(
27
+ rt, name, 0,
28
+ [this](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *, size_t) -> jsi::Value {
29
+ return this->resume(rt);
30
+ }
31
+ );
32
+ }
33
+
34
+ if (propName == "resultKind") {
35
+ return jsi::Function::createFromHostFunction(
36
+ rt, name, 0,
37
+ [this](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *, size_t) -> jsi::Value {
38
+ return this->resultKind(rt);
39
+ }
40
+ );
41
+ }
42
+
43
+ if (propName == "extractConnection") {
44
+ return jsi::Function::createFromHostFunction(
45
+ rt, name, 0,
46
+ [this](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *, size_t) -> jsi::Value {
47
+ return this->extractConnection(rt);
48
+ }
49
+ );
50
+ }
51
+
52
+ if (propName == "extractChanges") {
53
+ return jsi::Function::createFromHostFunction(
54
+ rt, name, 0,
55
+ [this](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *, size_t) -> jsi::Value {
56
+ return this->extractChanges(rt);
57
+ }
58
+ );
59
+ }
60
+
61
+ if (propName == "extractStats") {
62
+ return jsi::Function::createFromHostFunction(
63
+ rt, name, 0,
64
+ [this](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *, size_t) -> jsi::Value {
65
+ return this->extractStats(rt);
66
+ }
67
+ );
68
+ }
69
+
70
+ return jsi::Value::undefined();
71
+ }
72
+
73
+ void TursoSyncOperationHostObject::set(jsi::Runtime &rt, const jsi::PropNameID &name, const jsi::Value &value) {
74
+ // Read-only object
75
+ }
76
+
77
+ std::vector<jsi::PropNameID> TursoSyncOperationHostObject::getPropertyNames(jsi::Runtime &rt) {
78
+ std::vector<jsi::PropNameID> props;
79
+ props.emplace_back(jsi::PropNameID::forAscii(rt, "resume"));
80
+ props.emplace_back(jsi::PropNameID::forAscii(rt, "resultKind"));
81
+ props.emplace_back(jsi::PropNameID::forAscii(rt, "extractConnection"));
82
+ props.emplace_back(jsi::PropNameID::forAscii(rt, "extractChanges"));
83
+ props.emplace_back(jsi::PropNameID::forAscii(rt, "extractStats"));
84
+ return props;
85
+ }
86
+
87
+ // 1:1 C API mapping - NO logic, just calls through to C API
88
+
89
+ jsi::Value TursoSyncOperationHostObject::resume(jsi::Runtime &rt) {
90
+ const char* error = nullptr;
91
+ turso_status_code_t status = turso_sync_operation_resume(op_, &error);
92
+
93
+ if (status != TURSO_OK && status != TURSO_DONE && status != TURSO_IO) {
94
+ throwError(rt, error);
95
+ }
96
+
97
+ // Return status code (TURSO_DONE, TURSO_IO, etc.)
98
+ return jsi::Value(static_cast<int>(status));
99
+ }
100
+
101
+ jsi::Value TursoSyncOperationHostObject::resultKind(jsi::Runtime &rt) {
102
+ turso_sync_operation_result_type_t kind = turso_sync_operation_result_kind(op_);
103
+ return jsi::Value(static_cast<int>(kind));
104
+ }
105
+
106
+ jsi::Value TursoSyncOperationHostObject::extractConnection(jsi::Runtime &rt) {
107
+ const turso_connection_t* connection = nullptr;
108
+ turso_status_code_t status = turso_sync_operation_result_extract_connection(op_, &connection);
109
+
110
+ if (status != TURSO_OK) {
111
+ throw jsi::JSError(rt, "Failed to extract connection from operation result");
112
+ }
113
+
114
+ auto connectionObj = std::make_shared<TursoConnectionHostObject>(
115
+ const_cast<turso_connection_t*>(connection)
116
+ );
117
+ return jsi::Object::createFromHostObject(rt, connectionObj);
118
+ }
119
+
120
+ jsi::Value TursoSyncOperationHostObject::extractChanges(jsi::Runtime &rt) {
121
+ const turso_sync_changes_t* changes = nullptr;
122
+ turso_status_code_t status = turso_sync_operation_result_extract_changes(op_, &changes);
123
+
124
+ if (status != TURSO_OK) {
125
+ throw jsi::JSError(rt, "Failed to extract changes from operation result");
126
+ }
127
+
128
+ // If no changes, return null
129
+ if (!changes) {
130
+ return jsi::Value::null();
131
+ }
132
+
133
+ auto changesObj = std::make_shared<TursoSyncChangesHostObject>(
134
+ const_cast<turso_sync_changes_t*>(changes)
135
+ );
136
+ return jsi::Object::createFromHostObject(rt, changesObj);
137
+ }
138
+
139
+ jsi::Value TursoSyncOperationHostObject::extractStats(jsi::Runtime &rt) {
140
+ turso_sync_stats_t stats;
141
+ turso_status_code_t status = turso_sync_operation_result_extract_stats(op_, &stats);
142
+
143
+ if (status != TURSO_OK) {
144
+ throw jsi::JSError(rt, "Failed to extract stats from operation result");
145
+ }
146
+
147
+ // Convert stats to JS object
148
+ jsi::Object result(rt);
149
+ result.setProperty(rt, "cdcOperations", jsi::Value(static_cast<double>(stats.cdc_operations)));
150
+ result.setProperty(rt, "mainWalSize", jsi::Value(static_cast<double>(stats.main_wal_size)));
151
+ result.setProperty(rt, "revertWalSize", jsi::Value(static_cast<double>(stats.revert_wal_size)));
152
+ result.setProperty(rt, "lastPullUnixTime", jsi::Value(static_cast<double>(stats.last_pull_unix_time)));
153
+ result.setProperty(rt, "lastPushUnixTime", jsi::Value(static_cast<double>(stats.last_push_unix_time)));
154
+ result.setProperty(rt, "networkSentBytes", jsi::Value(static_cast<double>(stats.network_sent_bytes)));
155
+ result.setProperty(rt, "networkReceivedBytes", jsi::Value(static_cast<double>(stats.network_received_bytes)));
156
+
157
+ // Convert revision slice to string (if available)
158
+ if (stats.revision.ptr && stats.revision.len > 0) {
159
+ std::string revision(static_cast<const char*>(stats.revision.ptr), stats.revision.len);
160
+ result.setProperty(rt, "revision", jsi::String::createFromUtf8(rt, revision));
161
+ } else {
162
+ result.setProperty(rt, "revision", jsi::Value::null());
163
+ }
164
+
165
+ return result;
166
+ }
167
+
168
+ } // namespace turso
@@ -0,0 +1,53 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <memory>
5
+ #include <string>
6
+
7
+ // Forward declarations for Turso C API types
8
+ extern "C" {
9
+ struct turso_sync_operation;
10
+ struct turso_connection;
11
+ struct turso_sync_changes;
12
+ typedef struct turso_sync_operation turso_sync_operation_t;
13
+ typedef struct turso_connection turso_connection_t;
14
+ typedef struct turso_sync_changes turso_sync_changes_t;
15
+ }
16
+
17
+ namespace turso {
18
+
19
+ using namespace facebook;
20
+
21
+ /**
22
+ * TursoSyncOperationHostObject wraps turso_sync_operation_t* (async operation handle).
23
+ * This is a THIN wrapper - 1:1 mapping of SDK-KIT C API with NO logic.
24
+ * All logic belongs in TypeScript or Rust, not here.
25
+ */
26
+ class TursoSyncOperationHostObject : public jsi::HostObject {
27
+ public:
28
+ TursoSyncOperationHostObject(turso_sync_operation_t* op) : op_(op) {}
29
+ ~TursoSyncOperationHostObject();
30
+
31
+ // JSI HostObject interface
32
+ jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &name) override;
33
+ void set(jsi::Runtime &rt, const jsi::PropNameID &name, const jsi::Value &value) override;
34
+ std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
35
+
36
+ // Direct access to wrapped pointer (for internal use)
37
+ turso_sync_operation_t* getOperation() const { return op_; }
38
+
39
+ private:
40
+ turso_sync_operation_t* op_ = nullptr;
41
+
42
+ // Helper to throw JS errors
43
+ void throwError(jsi::Runtime &rt, const char *error);
44
+
45
+ // 1:1 C API mapping methods (NO logic - just calls through to C API)
46
+ jsi::Value resume(jsi::Runtime &rt);
47
+ jsi::Value resultKind(jsi::Runtime &rt);
48
+ jsi::Value extractConnection(jsi::Runtime &rt);
49
+ jsi::Value extractChanges(jsi::Runtime &rt);
50
+ jsi::Value extractStats(jsi::Runtime &rt);
51
+ };
52
+
53
+ } // namespace turso
@@ -0,0 +1,8 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import <React/RCTBridgeModule.h>
3
+
4
+ @interface Turso : NSObject <RCTBridgeModule>
5
+
6
+ @property (nonatomic, assign) BOOL setBridgeOnMainQueue;
7
+
8
+ @end
@@ -0,0 +1,95 @@
1
+ #import "TursoModule.h"
2
+
3
+ #import <React/RCTBridge+Private.h>
4
+ #import <React/RCTUtils.h>
5
+ #import <ReactCommon/RCTTurboModule.h>
6
+ #import <jsi/jsi.h>
7
+
8
+ #import "TursoHostObject.h"
9
+
10
+ @implementation Turso
11
+
12
+ @synthesize bridge = _bridge;
13
+
14
+ RCT_EXPORT_MODULE()
15
+
16
+ + (BOOL)requiresMainQueueSetup {
17
+ return YES;
18
+ }
19
+
20
+ - (NSDictionary *)constantsToExport {
21
+ // Get documents directory
22
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
23
+ NSString *documentsPath = [paths firstObject];
24
+
25
+ // Get library directory
26
+ NSArray *libraryPaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
27
+ NSString *libraryPath = [libraryPaths firstObject];
28
+
29
+ // Check for app group (for sharing data between app and extensions)
30
+ NSString *appGroup = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"Turso_AppGroup"];
31
+ if (appGroup) {
32
+ NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:appGroup];
33
+ if (containerURL) {
34
+ documentsPath = [containerURL path];
35
+ }
36
+ }
37
+
38
+ return @{
39
+ @"IOS_DOCUMENT_PATH": documentsPath ?: [NSNull null],
40
+ @"IOS_LIBRARY_PATH": libraryPath ?: [NSNull null],
41
+ @"ANDROID_DATABASE_PATH": [NSNull null],
42
+ @"ANDROID_FILES_PATH": [NSNull null],
43
+ @"ANDROID_EXTERNAL_FILES_PATH": [NSNull null]
44
+ };
45
+ }
46
+
47
+ - (void)setBridge:(RCTBridge *)bridge {
48
+ _bridge = bridge;
49
+
50
+ RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
51
+ if (!cxxBridge.runtime) {
52
+ return;
53
+ }
54
+
55
+ [self installLibrary];
56
+ }
57
+
58
+ - (void)installLibrary {
59
+ RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
60
+ if (!cxxBridge.runtime) {
61
+ return;
62
+ }
63
+
64
+ facebook::jsi::Runtime *runtime = (facebook::jsi::Runtime *)cxxBridge.runtime;
65
+ if (!runtime) {
66
+ return;
67
+ }
68
+
69
+ // Get the documents directory for database storage
70
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
71
+ NSString *documentsPath = [paths firstObject];
72
+
73
+ // Check for app group (for sharing data between app and extensions)
74
+ NSString *appGroup = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"Turso_AppGroup"];
75
+ if (appGroup) {
76
+ NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:appGroup];
77
+ if (containerURL) {
78
+ documentsPath = [containerURL path];
79
+ }
80
+ }
81
+
82
+ // Get the call invoker
83
+ auto callInvoker = _bridge.jsCallInvoker;
84
+
85
+ // Install the Turso module
86
+ turso::install(*runtime, callInvoker, [documentsPath UTF8String]);
87
+ }
88
+
89
+ // Synchronous method to check if the module is installed
90
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) {
91
+ [self installLibrary];
92
+ return @YES;
93
+ }
94
+
95
+ @end