@symbiote-native/network 3.0.2 → 3.0.3

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 (2) hide show
  1. package/README.md +43 -31
  2. package/package.json +15 -15
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @symbiote-native/network
2
2
 
3
3
  Port of [`expo-network`](https://docs.expo.dev/versions/latest/sdk/network/) for
4
- [SymbioteNative](../../README.md) — network connection state (type/connected/internet-reachable)
4
+ [SymbioteNative](../../README.md) - network connection state (type/connected/internet-reachable)
5
5
  with a change listener, device IP address, and airplane-mode detection, reachable from every
6
6
  adapter (React, Vue, Svelte, Solid, Angular), not just React.
7
7
 
@@ -25,43 +25,43 @@ npx @symbiote-native/cli new my-app --network
25
25
  npx @symbiote-native/cli add --network
26
26
  ```
27
27
 
28
- Either way: installs `@symbiote-native/network` and wires the native autolinking automatically —
28
+ Either way: installs `@symbiote-native/network` and wires the native autolinking automatically,
29
29
  see [`@symbiote-native/cli`](../cli).
30
30
 
31
31
  <details>
32
- <summary>Manual install (no CLI — installing and wiring native autolinking by hand)</summary>
32
+ <summary>Manual install (no CLI - installing and wiring native autolinking by hand)</summary>
33
33
 
34
34
  ```bash
35
35
  npm install @symbiote-native/network
36
36
  ```
37
37
 
38
38
  Depends on `expo-network` and `expo-modules-core` directly (regular dependencies, pinned to exact
39
- versions — never a caret range, since this package's `core/` is hand-ported against one specific
39
+ versions - never a caret range, since this package's `core/` is hand-ported against one specific
40
40
  native API shape and a newer resolve could silently drift the two apart). Never install
41
- `expo-network` yourself, and never add the `expo` package to this project — it bundles its own
41
+ `expo-network` yourself, and never add the `expo` package to this project - it bundles its own
42
42
  Metro/Babel pipeline that conflicts with this project's own.
43
43
 
44
44
  ### Required one-time step: native autolinking wiring
45
45
 
46
46
  Unlike a plain RN native module, `expo-network`'s native code is discovered by
47
- `expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism — this needs wiring
47
+ `expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism - this needs wiring
48
48
  into the native host app **once**, covering this package and every other `expo-modules-core`
49
49
  package (`@symbiote-native/battery`, `@symbiote-native/sensors`, `@symbiote-native/local-auth`)
50
50
  with zero further changes:
51
51
 
52
52
  | Platform | Touches |
53
53
  | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
54
- | iOS | `ios/Podfile` — add `use_expo_modules!` |
55
- | iOS | `AppDelegate.swift` — Expo's runtime-bootstrap hook |
56
- | Android | `settings.gradle` / `app/build.gradle` — resolve and include the Expo Gradle projects |
57
- | Android | `MainApplication.kt` — Expo's bootstrap hook, plus a hand-written native-module name map (there's no `expo` meta-package here to auto-generate one) |
54
+ | iOS | `ios/Podfile` - add `use_expo_modules!` |
55
+ | iOS | `AppDelegate.swift` - Expo's runtime-bootstrap hook |
56
+ | Android | `settings.gradle` / `app/build.gradle` - resolve and include the Expo Gradle projects |
57
+ | Android | `MainApplication.kt` - Expo's bootstrap hook, plus a hand-written native-module name map (there's no `expo` meta-package here to auto-generate one) |
58
58
 
59
- Full mechanics — the Podfile pieces that normally ship inside the `expo` package, the `expo`
60
- peer-dependency exclusion list — live in the `symbiote-expo-native-module` skill. Reference
59
+ Full mechanics - the Podfile pieces that normally ship inside the `expo` package, the `expo`
60
+ peer-dependency exclusion list - live in the `symbiote-expo-native-module` skill. Reference
61
61
  implementation: `examples/expo-react/ios/Podfile` and
62
62
  `examples/expo-react/android/app/src/main/java/com/canaryexpo/MainApplication.kt`.
63
63
 
64
- No platform permission string is needed for network's surface — connection state, IP address, and
64
+ No platform permission string is needed for network's surface - connection state, IP address, and
65
65
  airplane-mode detection all read system state with no runtime permission prompt on either
66
66
  platform.
67
67
 
@@ -70,28 +70,28 @@ platform.
70
70
  ## Shape
71
71
 
72
72
  ```
73
- src/core/ network.ts — get*Async functions + addNetworkStateListener subscription.
73
+ src/core/ network.ts - get*Async functions + addNetworkStateListener subscription.
74
74
  native-module.ts resolves the native module through expo-modules-core's
75
- requireNativeModule. types.ts — NetworkStateType enum, NetworkState,
75
+ requireNativeModule. types.ts - NetworkStateType enum, NetworkState,
76
76
  NetworkStateEvent, hand-ported from Network.types.ts.
77
- src/react/hooks/ @symbiote-native/network/react — useNetworkState
78
- src/vue/composables/ @symbiote-native/network/vue — useNetworkState (same name)
79
- src/svelte/runes/ @symbiote-native/network/svelte — useNetworkState (same name)
80
- src/solid/primitives/ @symbiote-native/network/solid — createNetworkState (returns an
77
+ src/react/hooks/ @symbiote-native/network/react - useNetworkState
78
+ src/vue/composables/ @symbiote-native/network/vue - useNetworkState (same name)
79
+ src/svelte/runes/ @symbiote-native/network/svelte - useNetworkState (same name)
80
+ src/solid/primitives/ @symbiote-native/network/solid - createNetworkState (returns an
81
81
  Accessor; Solid reserves `use*` for consuming existing state)
82
- src/angular/services/ @symbiote-native/network/angular — NetworkStateService (`.connect()`
82
+ src/angular/services/ @symbiote-native/network/angular - NetworkStateService (`.connect()`
83
83
  returns a Signal)
84
84
  ```
85
85
 
86
86
  Each adapter's hook/composable/rune/primitive/service is a thin lifecycle wrapper (seed from the
87
87
  one-shot `getNetworkStateAsync()` call, subscribe to `addNetworkStateListener`, unsubscribe on
88
- unmount) over the same `core` functions — the subscription logic is written once and shared by all
88
+ unmount) over the same `core` functions - the subscription logic is written once and shared by all
89
89
  of them.
90
90
 
91
91
  ## Use it
92
92
 
93
93
  ```tsx
94
- // React — examples/expo-react/screens/NetworkScreen.tsx
94
+ // React - examples/expo-react/screens/NetworkScreen.tsx
95
95
  import { useEffect, useState } from 'react';
96
96
  import {
97
97
  getIpAddressAsync,
@@ -128,7 +128,7 @@ function NetworkScreen() {
128
128
  ```
129
129
 
130
130
  ```vue
131
- <!-- Vue — examples/expo-vue-sfc/screens/NetworkScreen.vue -->
131
+ <!-- Vue - examples/expo-vue-sfc/screens/NetworkScreen.vue -->
132
132
  <script setup lang="ts">
133
133
  import { ref, watch } from 'vue';
134
134
  import {
@@ -195,7 +195,7 @@ watch(
195
195
  ```
196
196
 
197
197
  ```ts
198
- // Angular — examples/expo-angular/src/screens/NetworkScreen.ts
198
+ // Angular - examples/expo-angular/src/screens/NetworkScreen.ts
199
199
  import { Component, effect, inject, signal } from '@angular/core';
200
200
  import { SYMBIOTE_ELEMENTS } from '@symbiote-native/angular';
201
201
  import {
@@ -227,7 +227,7 @@ export class NetworkScreen {
227
227
  ```
228
228
 
229
229
  ```tsx
230
- // Solid — the accessor is CALLED; a Solid component body runs once, so a snapshot would freeze.
230
+ // Solid - the accessor is CALLED; a Solid component body runs once, so a snapshot would freeze.
231
231
  import { createSignal, onMount } from 'solid-js';
232
232
  import {
233
233
  getIpAddressAsync,
@@ -269,7 +269,7 @@ function NetworkScreen() {
269
269
 
270
270
  Each of the demo screens above also re-fetches the IP address and airplane-mode card
271
271
  whenever the live network state changes (toggling Wi-Fi/airplane mode on the device updates both
272
- cards together) — see the linked files for the full version, including the connection-type label
272
+ cards together) - see the linked files for the full version, including the connection-type label
273
273
  switch and the layout around it.
274
274
 
275
275
  ## API
@@ -285,7 +285,7 @@ addNetworkStateListener(listener): EventSubscription // fires whenever the n
285
285
  ```
286
286
 
287
287
  Plus `NetworkStateType` (enum: `NONE`/`UNKNOWN`/`CELLULAR`/`WIFI`/`BLUETOOTH`/`ETHERNET`/`WIMAX`/
288
- `VPN`/`OTHER`), `NetworkState`, `NetworkStateEvent` — ported from upstream's `Network.types.ts`.
288
+ `VPN`/`OTHER`), `NetworkState`, `NetworkStateEvent` - ported from upstream's `Network.types.ts`.
289
289
 
290
290
  ```ts
291
291
  import {
@@ -304,18 +304,30 @@ import { NetworkStateService } from '@symbiote-native/network/angular';
304
304
 
305
305
  `useNetworkState` (Solid: `createNetworkState`) seeds its initial value from a one-shot
306
306
  `getNetworkStateAsync()` call, then subscribes to `addNetworkStateListener` for updates, and
307
- unsubscribes on unmount — mirroring upstream's own `useNetworkState`. The Solid primitive returns
307
+ unsubscribes on unmount - mirroring upstream's own `useNetworkState`. The Solid primitive returns
308
308
  an `Accessor<NetworkState>` and subscribes from its body rather than an effect, so nothing can slip
309
309
  between the seed and the subscription.
310
310
 
311
+ ## Common questions
312
+
313
+ - **Wi-Fi without internet.** `isConnected` only says a network exists; use `isInternetReachable`.
314
+ - **`ERR_NETWORK_NO_ACCESS_NETWORKINFO` on Android.** Catch the rejection and treat it as offline.
315
+ - **Hook stuck offline after the app was frozen (Android).** Events can arrive out of order; call
316
+ `getNetworkStateAsync` on foreground.
317
+ - **Always `NONE` after an SDK update.** Reported upstream; check the network-state permission.
318
+
319
+ Sources: [expo/expo#14527](https://github.com/expo/expo/issues/14527),
320
+ [expo/expo#47846](https://github.com/expo/expo/issues/47846),
321
+ [expo/expo#33070](https://github.com/expo/expo/issues/33070).
322
+
311
323
  ## Test it
312
324
 
313
- No Fabric/Descriptor angle at all — network is a pure async-function + `EventEmitter` listener
325
+ No Fabric/Descriptor angle at all - network is a pure async-function + `EventEmitter` listener
314
326
  surface, never a view. Tests inject a fake native-module object in place of the real
315
327
  `requireNativeModule` resolution (`src/core/network.test.ts`,
316
328
  `src/{react,vue,svelte,solid,angular}/**/*.test.{ts,tsx}`, `vitest`), the same pattern
317
- `@symbiote-native/battery`/`@symbiote-native/sensors`/`@symbiote-native/local-auth` use — no
318
- `installFabric()`, no ViewConfig. Native rendering itself is verified on-device — see the parent
329
+ `@symbiote-native/battery`/`@symbiote-native/sensors`/`@symbiote-native/local-auth` use - no
330
+ `installFabric()`, no ViewConfig. Native rendering itself is verified on-device - see the parent
319
331
  [README](../../README.md).
320
332
 
321
333
  The Android/iOS native wiring is done across all six `examples/expo-*` canary apps
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/network",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "description": "expo-network wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. Network state (type/connected/internet-reachable) with a change listener, device IP address, and airplane-mode detection.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -70,7 +70,7 @@
70
70
  },
71
71
  "dependencies": {
72
72
  "expo-network": "57.0.1",
73
- "expo-modules-core": "57.0.5"
73
+ "expo-modules-core": "57.0.20"
74
74
  },
75
75
  "peerDependencies": {
76
76
  "@angular/core": ">=20",
@@ -80,12 +80,12 @@
80
80
  "solid-js": ">=1.9.0",
81
81
  "svelte": ">=5.56.0",
82
82
  "vue": ">=3.5.0",
83
- "@symbiote-native/angular": "^3.1.2",
84
- "@symbiote-native/engine": "^1.3.1",
85
- "@symbiote-native/react": "^3.0.4",
86
- "@symbiote-native/solid": "^3.0.4",
87
- "@symbiote-native/svelte": "^3.0.4",
88
- "@symbiote-native/vue": "^3.0.4"
83
+ "@symbiote-native/angular": "^3.2.0",
84
+ "@symbiote-native/engine": "^1.5.0",
85
+ "@symbiote-native/react": "^3.2.0",
86
+ "@symbiote-native/solid": "^3.1.0",
87
+ "@symbiote-native/svelte": "^3.1.0",
88
+ "@symbiote-native/vue": "^3.2.0"
89
89
  },
90
90
  "peerDependenciesMeta": {
91
91
  "@symbiote-native/angular": {
@@ -133,13 +133,13 @@
133
133
  "solid-js": "^1.9.14",
134
134
  "svelte": "^5.56.0",
135
135
  "typescript": "~6.0.0",
136
- "@symbiote-native/angular": "3.1.2",
137
- "@symbiote-native/engine": "1.3.1",
138
- "@symbiote-native/react": "3.0.4",
139
- "@symbiote-native/solid": "3.0.4",
140
- "@symbiote-native/svelte": "3.0.4",
141
- "@symbiote-native/test-utils": "0.4.4",
142
- "@symbiote-native/vue": "3.0.4"
136
+ "@symbiote-native/angular": "3.2.0",
137
+ "@symbiote-native/engine": "1.5.0",
138
+ "@symbiote-native/react": "3.2.0",
139
+ "@symbiote-native/solid": "3.1.0",
140
+ "@symbiote-native/svelte": "3.1.0",
141
+ "@symbiote-native/test-utils": "0.4.6",
142
+ "@symbiote-native/vue": "3.2.0"
143
143
  },
144
144
  "scripts": {
145
145
  "typecheck": "tsc --build",