@vishalsharma7nov/react-native-proto 0.2.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 (190) hide show
  1. package/android/src/main/java/com/vishalsharma7nov/reactnativeproto/ReactNativeProtoNativeGrpcModule.java +142 -0
  2. package/app.plugin.js +63 -0
  3. package/bin/react-native-proto.js +956 -0
  4. package/ios/ReactNativeProtoNativeGrpc.m +129 -0
  5. package/lib/commonjs/auth.js +72 -0
  6. package/lib/commonjs/auth.js.map +1 -0
  7. package/lib/commonjs/client-factory.js +81 -0
  8. package/lib/commonjs/client-factory.js.map +1 -0
  9. package/lib/commonjs/codecs.js +41 -0
  10. package/lib/commonjs/codecs.js.map +1 -0
  11. package/lib/commonjs/connect/envelope.js +100 -0
  12. package/lib/commonjs/connect/envelope.js.map +1 -0
  13. package/lib/commonjs/connect/errors.js +71 -0
  14. package/lib/commonjs/connect/errors.js.map +1 -0
  15. package/lib/commonjs/errors.js +54 -0
  16. package/lib/commonjs/errors.js.map +1 -0
  17. package/lib/commonjs/generated/create-api.js +29 -0
  18. package/lib/commonjs/generated/create-api.js.map +1 -0
  19. package/lib/commonjs/generated/message-types.js +2 -0
  20. package/lib/commonjs/generated/message-types.js.map +1 -0
  21. package/lib/commonjs/generated/messages.js +47 -0
  22. package/lib/commonjs/generated/messages.js.map +1 -0
  23. package/lib/commonjs/generated/messages.pb.js +2787 -0
  24. package/lib/commonjs/generated/messages.pb.js.map +1 -0
  25. package/lib/commonjs/generated/method-map.js +68 -0
  26. package/lib/commonjs/generated/method-map.js.map +1 -0
  27. package/lib/commonjs/index.js +283 -0
  28. package/lib/commonjs/index.js.map +1 -0
  29. package/lib/commonjs/interceptors.js +19 -0
  30. package/lib/commonjs/interceptors.js.map +1 -0
  31. package/lib/commonjs/logging.js +54 -0
  32. package/lib/commonjs/logging.js.map +1 -0
  33. package/lib/commonjs/metro/index.js +35 -0
  34. package/lib/commonjs/metro/index.js.map +1 -0
  35. package/lib/commonjs/metro/transformer.js +33 -0
  36. package/lib/commonjs/metro/transformer.js.map +1 -0
  37. package/lib/commonjs/mock-server/index.js +125 -0
  38. package/lib/commonjs/mock-server/index.js.map +1 -0
  39. package/lib/commonjs/native-grpc/index.js +242 -0
  40. package/lib/commonjs/native-grpc/index.js.map +1 -0
  41. package/lib/commonjs/offline-queue.js +137 -0
  42. package/lib/commonjs/offline-queue.js.map +1 -0
  43. package/lib/commonjs/package.json +1 -0
  44. package/lib/commonjs/path-templates.js +44 -0
  45. package/lib/commonjs/path-templates.js.map +1 -0
  46. package/lib/commonjs/react-query/index.js +30 -0
  47. package/lib/commonjs/react-query/index.js.map +1 -0
  48. package/lib/commonjs/streaming.js +251 -0
  49. package/lib/commonjs/streaming.js.map +1 -0
  50. package/lib/commonjs/transport.js +323 -0
  51. package/lib/commonjs/transport.js.map +1 -0
  52. package/lib/commonjs/types.js +6 -0
  53. package/lib/commonjs/types.js.map +1 -0
  54. package/lib/commonjs/validation/zod.js +48 -0
  55. package/lib/commonjs/validation/zod.js.map +1 -0
  56. package/lib/commonjs/version-check.js +102 -0
  57. package/lib/commonjs/version-check.js.map +1 -0
  58. package/lib/module/auth.js +67 -0
  59. package/lib/module/auth.js.map +1 -0
  60. package/lib/module/client-factory.js +77 -0
  61. package/lib/module/client-factory.js.map +1 -0
  62. package/lib/module/codecs.js +36 -0
  63. package/lib/module/codecs.js.map +1 -0
  64. package/lib/module/connect/envelope.js +93 -0
  65. package/lib/module/connect/envelope.js.map +1 -0
  66. package/lib/module/connect/errors.js +65 -0
  67. package/lib/module/connect/errors.js.map +1 -0
  68. package/lib/module/errors.js +46 -0
  69. package/lib/module/errors.js.map +1 -0
  70. package/lib/module/generated/create-api.js +13 -0
  71. package/lib/module/generated/create-api.js.map +1 -0
  72. package/lib/module/generated/message-types.js +2 -0
  73. package/lib/module/generated/message-types.js.map +1 -0
  74. package/lib/module/generated/messages.js +43 -0
  75. package/lib/module/generated/messages.js.map +1 -0
  76. package/lib/module/generated/messages.pb.js +2787 -0
  77. package/lib/module/generated/messages.pb.js.map +1 -0
  78. package/lib/module/generated/method-map.js +64 -0
  79. package/lib/module/generated/method-map.js.map +1 -0
  80. package/lib/module/index.js +53 -0
  81. package/lib/module/index.js.map +1 -0
  82. package/lib/module/interceptors.js +15 -0
  83. package/lib/module/interceptors.js.map +1 -0
  84. package/lib/module/logging.js +50 -0
  85. package/lib/module/logging.js.map +1 -0
  86. package/lib/module/metro/index.js +25 -0
  87. package/lib/module/metro/index.js.map +1 -0
  88. package/lib/module/metro/transformer.js +29 -0
  89. package/lib/module/metro/transformer.js.map +1 -0
  90. package/lib/module/mock-server/index.js +120 -0
  91. package/lib/module/mock-server/index.js.map +1 -0
  92. package/lib/module/native-grpc/index.js +233 -0
  93. package/lib/module/native-grpc/index.js.map +1 -0
  94. package/lib/module/offline-queue.js +132 -0
  95. package/lib/module/offline-queue.js.map +1 -0
  96. package/lib/module/package.json +1 -0
  97. package/lib/module/path-templates.js +39 -0
  98. package/lib/module/path-templates.js.map +1 -0
  99. package/lib/module/react-query/index.js +25 -0
  100. package/lib/module/react-query/index.js.map +1 -0
  101. package/lib/module/streaming.js +246 -0
  102. package/lib/module/streaming.js.map +1 -0
  103. package/lib/module/transport.js +316 -0
  104. package/lib/module/transport.js.map +1 -0
  105. package/lib/module/types.js +4 -0
  106. package/lib/module/types.js.map +1 -0
  107. package/lib/module/validation/zod.js +43 -0
  108. package/lib/module/validation/zod.js.map +1 -0
  109. package/lib/module/version-check.js +93 -0
  110. package/lib/module/version-check.js.map +1 -0
  111. package/lib/typescript/src/auth.d.ts +26 -0
  112. package/lib/typescript/src/auth.d.ts.map +1 -0
  113. package/lib/typescript/src/client-factory.d.ts +7 -0
  114. package/lib/typescript/src/client-factory.d.ts.map +1 -0
  115. package/lib/typescript/src/codecs.d.ts +5 -0
  116. package/lib/typescript/src/codecs.d.ts.map +1 -0
  117. package/lib/typescript/src/connect/envelope.d.ts +18 -0
  118. package/lib/typescript/src/connect/envelope.d.ts.map +1 -0
  119. package/lib/typescript/src/connect/errors.d.ts +11 -0
  120. package/lib/typescript/src/connect/errors.d.ts.map +1 -0
  121. package/lib/typescript/src/errors.d.ts +21 -0
  122. package/lib/typescript/src/errors.d.ts.map +1 -0
  123. package/lib/typescript/src/generated/create-api.d.ts +34 -0
  124. package/lib/typescript/src/generated/create-api.d.ts.map +1 -0
  125. package/lib/typescript/src/generated/message-types.d.ts +54 -0
  126. package/lib/typescript/src/generated/message-types.d.ts.map +1 -0
  127. package/lib/typescript/src/generated/messages.d.ts +17 -0
  128. package/lib/typescript/src/generated/messages.d.ts.map +1 -0
  129. package/lib/typescript/src/generated/method-map.d.ts +7 -0
  130. package/lib/typescript/src/generated/method-map.d.ts.map +1 -0
  131. package/lib/typescript/src/index.d.ts +53 -0
  132. package/lib/typescript/src/index.d.ts.map +1 -0
  133. package/lib/typescript/src/interceptors.d.ts +17 -0
  134. package/lib/typescript/src/interceptors.d.ts.map +1 -0
  135. package/lib/typescript/src/logging.d.ts +16 -0
  136. package/lib/typescript/src/logging.d.ts.map +1 -0
  137. package/lib/typescript/src/metro/index.d.ts +15 -0
  138. package/lib/typescript/src/metro/index.d.ts.map +1 -0
  139. package/lib/typescript/src/metro/transformer.d.ts +16 -0
  140. package/lib/typescript/src/metro/transformer.d.ts.map +1 -0
  141. package/lib/typescript/src/mock-server/index.d.ts +27 -0
  142. package/lib/typescript/src/mock-server/index.d.ts.map +1 -0
  143. package/lib/typescript/src/native-grpc/index.d.ts +36 -0
  144. package/lib/typescript/src/native-grpc/index.d.ts.map +1 -0
  145. package/lib/typescript/src/offline-queue.d.ts +47 -0
  146. package/lib/typescript/src/offline-queue.d.ts.map +1 -0
  147. package/lib/typescript/src/path-templates.d.ts +17 -0
  148. package/lib/typescript/src/path-templates.d.ts.map +1 -0
  149. package/lib/typescript/src/react-query/index.d.ts +14 -0
  150. package/lib/typescript/src/react-query/index.d.ts.map +1 -0
  151. package/lib/typescript/src/streaming.d.ts +10 -0
  152. package/lib/typescript/src/streaming.d.ts.map +1 -0
  153. package/lib/typescript/src/transport.d.ts +19 -0
  154. package/lib/typescript/src/transport.d.ts.map +1 -0
  155. package/lib/typescript/src/types.d.ts +78 -0
  156. package/lib/typescript/src/types.d.ts.map +1 -0
  157. package/lib/typescript/src/validation/zod.d.ts +33 -0
  158. package/lib/typescript/src/validation/zod.d.ts.map +1 -0
  159. package/lib/typescript/src/version-check.d.ts +40 -0
  160. package/lib/typescript/src/version-check.d.ts.map +1 -0
  161. package/metro/index.js +23 -0
  162. package/metro/transformer.js +21 -0
  163. package/package.json +144 -0
  164. package/react-native-proto.podspec +15 -0
  165. package/src/auth.ts +97 -0
  166. package/src/client-factory.ts +109 -0
  167. package/src/codecs.ts +42 -0
  168. package/src/connect/envelope.ts +112 -0
  169. package/src/connect/errors.ts +86 -0
  170. package/src/errors.ts +81 -0
  171. package/src/generated/create-api.ts +40 -0
  172. package/src/generated/message-types.ts +63 -0
  173. package/src/generated/messages.pb.js +3207 -0
  174. package/src/generated/messages.ts +45 -0
  175. package/src/generated/method-map.ts +71 -0
  176. package/src/index.ts +113 -0
  177. package/src/interceptors.ts +32 -0
  178. package/src/logging.ts +67 -0
  179. package/src/metro/index.ts +27 -0
  180. package/src/metro/transformer.ts +38 -0
  181. package/src/mock-server/index.ts +164 -0
  182. package/src/native-grpc/index.ts +302 -0
  183. package/src/offline-queue.ts +160 -0
  184. package/src/path-templates.ts +65 -0
  185. package/src/react-query/index.ts +40 -0
  186. package/src/streaming.ts +326 -0
  187. package/src/transport.ts +427 -0
  188. package/src/types.ts +94 -0
  189. package/src/validation/zod.ts +75 -0
  190. package/src/version-check.ts +121 -0
@@ -0,0 +1,326 @@
1
+ import {
2
+ CONNECT_FLAG_END_STREAM,
3
+ decodeConnectEnvelopes,
4
+ encodeConnectEnvelope,
5
+ readConnectEnvelopeStream,
6
+ } from './connect/envelope';
7
+ import {
8
+ bytesToUtf8,
9
+ connectErrorFromJson,
10
+ tryParseConnectError,
11
+ } from './connect/errors';
12
+ import { ProtoClientError } from './errors';
13
+ import { buildHeaders, unaryCall, type ResolvedTransportConfig } from './transport';
14
+ import type { CodecRegistry, MessageCodec, StreamCallInput } from './types';
15
+
16
+ async function collectRequests(
17
+ input: StreamCallInput
18
+ ): Promise<Record<string, unknown>[]> {
19
+ if (input.requests) {
20
+ const list: Record<string, unknown>[] = [];
21
+ for await (const item of input.requests as AsyncIterable<
22
+ Record<string, unknown>
23
+ >) {
24
+ list.push(item);
25
+ }
26
+ return list;
27
+ }
28
+ return [input.request ?? {}];
29
+ }
30
+
31
+ function buildConnectRequestBody(
32
+ entryKind: string,
33
+ requests: Record<string, unknown>[],
34
+ requestCodec: MessageCodec
35
+ ): Uint8Array {
36
+ const useEnvelopedRequest =
37
+ entryKind === 'clientStreaming' ||
38
+ entryKind === 'bidi' ||
39
+ requests.length > 1;
40
+
41
+ if (!useEnvelopedRequest) {
42
+ return requestCodec.encode(requests[0] ?? {});
43
+ }
44
+
45
+ const frames: Uint8Array[] = [];
46
+ for (let i = 0; i < requests.length; i += 1) {
47
+ frames.push(encodeConnectEnvelope(requestCodec.encode(requests[i] ?? {}), 0));
48
+ }
49
+ if (entryKind === 'clientStreaming' || entryKind === 'bidi') {
50
+ frames.push(encodeConnectEnvelope(new Uint8Array(0), CONNECT_FLAG_END_STREAM));
51
+ }
52
+
53
+ let bodyLength = 0;
54
+ for (let i = 0; i < frames.length; i += 1) {
55
+ bodyLength += frames[i]!.byteLength;
56
+ }
57
+ const body = new Uint8Array(bodyLength);
58
+ let offset = 0;
59
+ for (let i = 0; i < frames.length; i += 1) {
60
+ body.set(frames[i]!, offset);
61
+ offset += frames[i]!.byteLength;
62
+ }
63
+ return body;
64
+ }
65
+
66
+ function throwIfEndStreamError(
67
+ data: Uint8Array,
68
+ rpcPath: string,
69
+ status?: number
70
+ ): void {
71
+ if (data.byteLength === 0) {
72
+ return;
73
+ }
74
+ const json = JSON.parse(bytesToUtf8(data)) as {
75
+ error?: { code?: string; message?: string };
76
+ code?: string;
77
+ message?: string;
78
+ };
79
+ const errBody = json.error ?? json;
80
+ if (errBody.code || errBody.message) {
81
+ throw connectErrorFromJson(errBody, rpcPath, status);
82
+ }
83
+ }
84
+
85
+ async function* yieldConnectEnvelopes(
86
+ envelopes: { flags: number; data: Uint8Array }[],
87
+ responseCodec: MessageCodec,
88
+ input: StreamCallInput,
89
+ status?: number
90
+ ): AsyncGenerator<Record<string, unknown>, void, undefined> {
91
+ for (let i = 0; i < envelopes.length; i += 1) {
92
+ const envelope = envelopes[i]!;
93
+ if (envelope.flags & CONNECT_FLAG_END_STREAM) {
94
+ throwIfEndStreamError(envelope.data, input.entry.rpcPath, status);
95
+ return;
96
+ }
97
+ const message = responseCodec.decode(envelope.data);
98
+ if (input.onMessage) {
99
+ input.onMessage(message);
100
+ }
101
+ yield message;
102
+ }
103
+ }
104
+
105
+ async function fetchConnectStreamResponse(
106
+ config: ResolvedTransportConfig,
107
+ input: StreamCallInput,
108
+ requestBody: Uint8Array
109
+ ): Promise<Response> {
110
+ const path = config.pathForMethod(input.entry);
111
+ const url = `${config.baseUrl}${path.startsWith('/') ? path : `/${path}`}`;
112
+ const headers = await buildHeaders(
113
+ config,
114
+ 'application/connect+proto',
115
+ input.entry.rpcPath,
116
+ input.headers
117
+ );
118
+ headers['Connect-Protocol-Version'] = '1';
119
+ headers.Accept = 'application/connect+proto';
120
+
121
+ const controller = new AbortController();
122
+ const timeoutId = setTimeout(() => controller.abort(), config.timeoutMs);
123
+ const onAbort = () => controller.abort();
124
+
125
+ if (input.signal) {
126
+ if (input.signal.aborted) {
127
+ clearTimeout(timeoutId);
128
+ throw new ProtoClientError({
129
+ code: 'ABORTED',
130
+ message: 'Request was aborted before send',
131
+ rpcPath: input.entry.rpcPath,
132
+ });
133
+ }
134
+ input.signal.addEventListener('abort', onAbort, { once: true });
135
+ }
136
+
137
+ try {
138
+ try {
139
+ return await config.fetchImpl(url, {
140
+ method: 'POST',
141
+ headers,
142
+ body: requestBody as unknown as BodyInit,
143
+ signal: controller.signal,
144
+ });
145
+ } catch (cause) {
146
+ if (controller.signal.aborted) {
147
+ throw new ProtoClientError({
148
+ code: input.signal?.aborted ? 'ABORTED' : 'TIMEOUT',
149
+ message: input.signal?.aborted
150
+ ? 'Request was aborted'
151
+ : `Stream timed out after ${config.timeoutMs}ms`,
152
+ rpcPath: input.entry.rpcPath,
153
+ cause,
154
+ retryable: !input.signal?.aborted,
155
+ });
156
+ }
157
+ throw new ProtoClientError({
158
+ code: 'NETWORK',
159
+ message: `Network error streaming ${input.entry.rpcPath}`,
160
+ rpcPath: input.entry.rpcPath,
161
+ cause,
162
+ retryable: true,
163
+ });
164
+ }
165
+ } finally {
166
+ clearTimeout(timeoutId);
167
+ if (input.signal) {
168
+ input.signal.removeEventListener('abort', onAbort);
169
+ }
170
+ }
171
+ }
172
+
173
+ function assertOkConnectResponse(response: Response, rpcPath: string): void {
174
+ if (response.ok) {
175
+ return;
176
+ }
177
+ // Body already consumed by caller via text() if needed — here we only throw generic.
178
+ throw new ProtoClientError({
179
+ code: 'HTTP',
180
+ message: `HTTP ${response.status} for ${rpcPath}`,
181
+ status: response.status,
182
+ rpcPath,
183
+ retryable: response.status >= 500,
184
+ });
185
+ }
186
+
187
+ async function* streamConnect(
188
+ config: ResolvedTransportConfig,
189
+ codecs: CodecRegistry,
190
+ input: StreamCallInput
191
+ ): AsyncGenerator<Record<string, unknown>, void, undefined> {
192
+ const { entry } = input;
193
+ const requestCodec = codecs.get(entry.requestType);
194
+ const responseCodec = codecs.get(entry.responseType);
195
+ if (!requestCodec || !responseCodec) {
196
+ throw new ProtoClientError({
197
+ code: 'INVALID_ARGUMENT',
198
+ message: `Missing codec for ${entry.requestType} or ${entry.responseType}`,
199
+ rpcPath: entry.rpcPath,
200
+ });
201
+ }
202
+
203
+ const requests = await collectRequests(input);
204
+ if (
205
+ (entry.kind === 'clientStreaming' || entry.kind === 'bidi') &&
206
+ requests.length === 0
207
+ ) {
208
+ throw new ProtoClientError({
209
+ code: 'INVALID_ARGUMENT',
210
+ message: 'Client streaming requires at least one request message',
211
+ rpcPath: entry.rpcPath,
212
+ });
213
+ }
214
+
215
+ const requestBody = buildConnectRequestBody(entry.kind, requests, requestCodec);
216
+ const response = await fetchConnectStreamResponse(config, input, requestBody);
217
+
218
+ if (!response.ok) {
219
+ let text = '';
220
+ try {
221
+ text = await response.text();
222
+ } catch {
223
+ text = '';
224
+ }
225
+ const connectErr = tryParseConnectError(text, entry.rpcPath, response.status);
226
+ if (connectErr) {
227
+ throw connectErr;
228
+ }
229
+ assertOkConnectResponse(response, entry.rpcPath);
230
+ }
231
+
232
+ const contentType = response.headers.get('content-type') || '';
233
+
234
+ if (response.body && typeof response.body.getReader === 'function') {
235
+ for await (const envelope of readConnectEnvelopeStream(
236
+ response.body,
237
+ config.maxResponseBytes
238
+ )) {
239
+ if (envelope.flags & CONNECT_FLAG_END_STREAM) {
240
+ throwIfEndStreamError(envelope.data, entry.rpcPath, response.status);
241
+ return;
242
+ }
243
+ const message = responseCodec.decode(envelope.data);
244
+ if (input.onMessage) {
245
+ input.onMessage(message);
246
+ }
247
+ yield message;
248
+ }
249
+ return;
250
+ }
251
+
252
+ const buffer = new Uint8Array(await response.arrayBuffer());
253
+ if (buffer.byteLength > config.maxResponseBytes) {
254
+ throw new ProtoClientError({
255
+ code: 'PAYLOAD_TOO_LARGE',
256
+ message: 'Stream response exceeds maxResponseBytes',
257
+ rpcPath: entry.rpcPath,
258
+ });
259
+ }
260
+
261
+ const looksLikeRawProto =
262
+ contentType.includes('proto') &&
263
+ !contentType.includes('connect') &&
264
+ buffer.byteLength > 0 &&
265
+ buffer[0]! > 2;
266
+
267
+ if (looksLikeRawProto) {
268
+ const message = await unaryCall(config, codecs, input);
269
+ if (input.onMessage) {
270
+ input.onMessage(message);
271
+ }
272
+ yield message;
273
+ return;
274
+ }
275
+
276
+ const envelopes = decodeConnectEnvelopes(buffer);
277
+ if (envelopes.length === 0 && buffer.byteLength > 0) {
278
+ const message = responseCodec.decode(buffer);
279
+ if (input.onMessage) {
280
+ input.onMessage(message);
281
+ }
282
+ yield message;
283
+ return;
284
+ }
285
+
286
+ yield* yieldConnectEnvelopes(envelopes, responseCodec, input, response.status);
287
+ }
288
+
289
+ /**
290
+ * Streaming helpers.
291
+ * - HTTP+protobuf: unary only
292
+ * - Connect: server-streaming via envelope frames; client/bidi send enveloped requests
293
+ * - native-grpc: bridge streaming when available
294
+ */
295
+ export async function* streamCall(
296
+ config: ResolvedTransportConfig,
297
+ codecs: CodecRegistry,
298
+ input: StreamCallInput
299
+ ): AsyncGenerator<Record<string, unknown>, void, undefined> {
300
+ const { entry } = input;
301
+
302
+ if (entry.kind === 'unary') {
303
+ throw new ProtoClientError({
304
+ code: 'UNSUPPORTED',
305
+ message: `Method ${entry.rpcPath} is unary; use the promise API`,
306
+ rpcPath: entry.rpcPath,
307
+ });
308
+ }
309
+
310
+ if (config.transport === 'http') {
311
+ throw new ProtoClientError({
312
+ code: 'UNSUPPORTED',
313
+ message:
314
+ 'Streaming requires transport "connect" or "native-grpc". HTTP+protobuf is unary-only.',
315
+ rpcPath: entry.rpcPath,
316
+ });
317
+ }
318
+
319
+ if (config.transport === 'native-grpc') {
320
+ const { nativeGrpcStream } = await import('./native-grpc');
321
+ yield* nativeGrpcStream(config, codecs, input);
322
+ return;
323
+ }
324
+
325
+ yield* streamConnect(config, codecs, input);
326
+ }