@symbiote-native/background-task 0.1.2 → 0.1.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 (2) hide show
  1. package/README.md +41 -27
  2. package/package.json +16 -16
package/README.md CHANGED
@@ -1,16 +1,17 @@
1
1
  # @symbiote-native/background-task
2
2
 
3
- A wrapper package for [SymbioteNative](../../README.md) that makes
4
- [`expo-background-task`](https://github.com/expo/expo/tree/main/packages/expo-background-task)
5
- usable from **every** adapter — React, Vue, Svelte, Solid, and Angular. Like
6
- [`@symbiote-native/task-manager`](../task-manager), every export is a plain function or a
7
- one-time module-load side effect, so there is no hook/composable/service to wrap: the React,
8
- Vue, Svelte, Solid, and Angular entry points are plain re-exports of the same `core`.
3
+ Sync, clean up or upload while the app is closed, when the OS decides the moment is right. One API
4
+ for every [SymbioteNative](../../README.md) adapter (React, Vue, Svelte, Solid and Angular).
5
+
6
+ It wraps [`expo-background-task`](https://github.com/expo/expo/tree/main/packages/expo-background-task).
7
+ Like [`@symbiote-native/task-manager`](../task-manager), every export is a plain function or a
8
+ one-time module-load side effect, so there is no hook, composable or service to wrap: every adapter
9
+ entry point is a plain re-export of the same `core`.
9
10
 
10
11
  This is the modern replacement for [`@symbiote-native/background-fetch`](../background-fetch),
11
12
  built on `BGTaskScheduler` (iOS) / `WorkManager` (Android) instead of a periodic-fetch alarm.
12
13
  Like its sibling, this package registers a task with native so it fires **in the background on
13
- the OS's own schedule** — it does not define what the task does. Define the task first via
14
+ the OS's own schedule** - it does not define what the task does. Define the task first via
14
15
  [`@symbiote-native/task-manager`](../task-manager)'s `defineTask`, then register it for periodic
15
16
  execution via this package's `registerTaskAsync`.
16
17
 
@@ -29,33 +30,33 @@ npx @symbiote-native/cli add --background-task
29
30
  ```
30
31
 
31
32
  Either way: installs `@symbiote-native/background-task` + `@symbiote-native/task-manager` and
32
- wires the native autolinking automatically — see [`@symbiote-native/cli`](../cli).
33
+ wires the native autolinking automatically - see [`@symbiote-native/cli`](../cli).
33
34
 
34
35
  <details>
35
- <summary>Manual install (no CLI — installing and wiring native autolinking by hand)</summary>
36
+ <summary>Manual install (no CLI - installing and wiring native autolinking by hand)</summary>
36
37
 
37
38
  ```bash
38
39
  npm install @symbiote-native/background-task @symbiote-native/task-manager
39
40
  ```
40
41
 
41
42
  `expo-background-task` and `expo-modules-core` come along as regular dependencies, pinned to
42
- exact versions — never install them yourself, and never add the `expo` meta-package to your
43
+ exact versions - never install them yourself, and never add the `expo` meta-package to your
43
44
  project.
44
45
 
45
46
  ## Required one-time step: native autolinking wiring
46
47
 
47
- Same one-time step as every other `expo-modules-core` package this project ships — see
48
+ Same one-time step as every other `expo-modules-core` package this project ships - see
48
49
  [`@symbiote-native/local-auth`'s README](../local-auth/README.md#required-one-time-step-native-autolinking-wiring)
49
50
  and the `symbiote-expo-native-module` project skill.
50
51
 
51
52
  iOS also needs `UIBackgroundModes: processing` and `BGTaskSchedulerPermittedIdentifiers` (the
52
53
  fixed identifier baked into `expo-background-task`'s own native Swift source,
53
- `BackgroundTaskConstants.swift`) in the app's Info.plist — `native-link.json`'s `ios.infoPlistArrayKeys`
54
+ `BackgroundTaskConstants.swift`) in the app's Info.plist - `native-link.json`'s `ios.infoPlistArrayKeys`
54
55
  covers this ARRAY-valued case (see `@symbiote-native/expo-modules-link`), so it's wired
55
56
  automatically by the same postinstall step, no manual edit needed. Android needs no manual step
56
57
  either; its `AndroidManifest.xml` declares no extra permission.
57
58
 
58
- **The iOS Simulator has no `BGTaskScheduler` support at all** (Apple's own limitation — physical
59
+ **The iOS Simulator has no `BGTaskScheduler` support at all** (Apple's own limitation - physical
59
60
  device only), so `BackgroundTaskStatus` reads `Restricted` there and `registerTaskAsync` is a
60
61
  no-op regardless of Info.plist. Test registration on a real device.
61
62
 
@@ -69,7 +70,7 @@ src/core/ getStatusAsync / registerTaskAsync / unregisterTaskAsync /
69
70
  BackgroundTaskStatus / BackgroundTaskResult / IBackgroundTaskOptions.
70
71
  native-module.ts resolves the native module via expo-modules-core's
71
72
  requireNativeModule.
72
- src/angular/ @symbiote-native/background-task/angular — export * from '../core'
73
+ src/angular/ @symbiote-native/background-task/angular - export * from '../core'
73
74
  ```
74
75
 
75
76
  `./react`, `./vue`, `./svelte`, and `./solid` are `exports`-map aliases straight onto
@@ -79,7 +80,7 @@ src/angular/ @symbiote-native/background-task/angular — export * from '../cor
79
80
  ## Use it
80
81
 
81
82
  ```ts
82
- // index.ts, alongside AppRegistry.registerComponent — identical on every adapter
83
+ // index.ts, alongside AppRegistry.registerComponent - identical on every adapter
83
84
  import { defineTask } from '@symbiote-native/task-manager';
84
85
  import {
85
86
  registerTaskAsync,
@@ -103,7 +104,7 @@ await registerTaskAsync(SYNC_TASK, { minimumInterval: 15 });
103
104
  ```
104
105
 
105
106
  `@symbiote-native/task-manager` is the primitive both this package and
106
- [`@symbiote-native/background-fetch`](../background-fetch) build on — `defineTask` lives there,
107
+ [`@symbiote-native/background-fetch`](../background-fetch) build on - `defineTask` lives there,
107
108
  `registerTaskAsync`/`unregisterTaskAsync` live here. `defineTask` must run at the top of the JS
108
109
  bundle, outside any component, for the same reason documented in task-manager's own README: the
109
110
  app can be launched headlessly to run a background task, with no views mounted.
@@ -117,7 +118,7 @@ import {
117
118
 
118
119
  const status = await getStatusAsync();
119
120
 
120
- // iOS only — the system can interrupt a running background task before it finishes.
121
+ // iOS only - the system can interrupt a running background task before it finishes.
121
122
  const subscription = addExpirationListener(() => {
122
123
  console.warn('background-sync was interrupted before it finished');
123
124
  });
@@ -126,7 +127,7 @@ subscription.remove();
126
127
  await unregisterTaskAsync(SYNC_TASK); // stop receiving executions of it
127
128
  ```
128
129
 
129
- Identical import surface on every adapter — `@symbiote-native/background-task/react`,
130
+ Identical import surface on every adapter - `@symbiote-native/background-task/react`,
130
131
  `/vue`, `/svelte`, `/solid`, `/angular` all re-export the same functions.
131
132
 
132
133
  ## API
@@ -139,32 +140,45 @@ triggerTaskWorkerForTestingAsync(): Promise<boolean>
139
140
  addExpirationListener(listener: () => void): { remove: () => void }
140
141
  ```
141
142
 
142
- Plus `BackgroundTaskStatus`, `BackgroundTaskResult`, `IBackgroundTaskOptions` — ported from
143
+ Plus `BackgroundTaskStatus`, `BackgroundTaskResult`, `IBackgroundTaskOptions` - ported from
143
144
  upstream's `BackgroundTask.types.ts`, the options type renamed with this repo's `I`-prefix
144
145
  convention for exported types (`ts-js-best-practices`).
145
146
 
146
147
  ## Notes
147
148
 
148
149
  - **`registerTaskAsync` requires the task to already be defined.** It throws if
149
- `@symbiote-native/task-manager`'s `isTaskDefined(taskName)` is `false` — call `defineTask`
150
+ `@symbiote-native/task-manager`'s `isTaskDefined(taskName)` is `false` - call `defineTask`
150
151
  first.
151
152
  - **`registerTaskAsync` is a no-op, twice over.** It skips silently (with a one-time console
152
- warning) when the environment reports `BackgroundTaskStatus.Restricted` — the iOS Simulator has
153
- no `BGTaskScheduler` support at all — and it skips again, quietly, when the task is already
153
+ warning) when the environment reports `BackgroundTaskStatus.Restricted` - the iOS Simulator has
154
+ no `BGTaskScheduler` support at all - and it skips again, quietly, when the task is already
154
155
  registered (checked via `@symbiote-native/task-manager`'s `isTaskRegisteredAsync`).
155
156
  - **`triggerTaskWorkerForTestingAsync` only runs in a dev build.** It always resolves `false` in
156
- production, matching upstream's own `__DEV__` gate — read here through a narrow local type
157
+ production, matching upstream's own `__DEV__` gate - read here through a narrow local type
157
158
  rather than the bare RN global, since this package's own type graph never imports
158
159
  `react-native`.
159
160
  - **Expo Go is out of scope.** Upstream also warns when running inside Expo Go
160
161
  (`isRunningInExpoGo`, imported from the `expo` meta-package) and reports
161
- `BackgroundTaskStatus.Restricted` there. This project never installs `expo` — every app here is
162
- a bare/dev-client build, never Expo Go — so that branch has no equivalent here and is
162
+ `BackgroundTaskStatus.Restricted` there. This project never installs `expo` - every app here is
163
+ a bare/dev-client build, never Expo Go - so that branch has no equivalent here and is
163
164
  intentionally not ported.
164
165
 
166
+ ## Common questions
167
+
168
+ - **Nothing runs on the iOS Simulator.** Background tasks need a physical device.
169
+ - **`triggerTaskWorkerForTestingAsync` does nothing on iOS.** `BGTaskSchedulerPermittedIdentifiers`
170
+ must contain `com.expo.modules.backgroundtask.processing` in Info.plist; rebuild after adding it.
171
+ - **`minimumInterval`.** A hint only; the OS decides when to run.
172
+ - **Status ignores Background App Refresh on iOS.** Reported upstream; do not rely on it alone.
173
+
174
+ Sources: [Expo docs: BackgroundTask](https://docs.expo.dev/versions/latest/sdk/background-task/),
175
+ [expo/expo#40440](https://github.com/expo/expo/issues/40440),
176
+ [expo/expo#48786](https://github.com/expo/expo/issues/48786),
177
+ [expo/expo#35350](https://github.com/expo/expo/pull/35350).
178
+
165
179
  ## Test it
166
180
 
167
- No Fabric/Descriptor angle at all — every function here is a pure async-function surface plus one
181
+ No Fabric/Descriptor angle at all - every function here is a pure async-function surface plus one
168
182
  event subscription, never a view or per-instance state. Tests inject a fake native-module object
169
183
  in place of the real `requireNativeModule` resolution and a fake `@symbiote-native/task-manager`
170
- module (`src/core/background-task.test.ts`) — no `installFabric()`, no ViewConfig.
184
+ module (`src/core/background-task.test.ts`) - no `installFabric()`, no ViewConfig.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/background-task",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "expo-background-task wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. Periodic background work via BGTaskScheduler (iOS) / WorkManager (Android), registered through @symbiote-native/task-manager.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -72,8 +72,8 @@
72
72
  },
73
73
  "dependencies": {
74
74
  "expo-background-task": "57.0.15",
75
- "expo-modules-core": "57.0.5",
76
- "@symbiote-native/task-manager": "0.1.2"
75
+ "expo-modules-core": "57.0.20",
76
+ "@symbiote-native/task-manager": "0.1.4"
77
77
  },
78
78
  "peerDependencies": {
79
79
  "@angular/core": ">=20",
@@ -83,12 +83,12 @@
83
83
  "solid-js": ">=1.9.0",
84
84
  "svelte": ">=5.56.0",
85
85
  "vue": ">=3.5.0",
86
- "@symbiote-native/angular": "^3.1.2",
87
- "@symbiote-native/engine": "^1.3.1",
88
- "@symbiote-native/react": "^3.0.4",
89
- "@symbiote-native/solid": "^3.0.4",
90
- "@symbiote-native/svelte": "^3.0.4",
91
- "@symbiote-native/vue": "^3.0.4"
86
+ "@symbiote-native/angular": "^3.3.0",
87
+ "@symbiote-native/engine": "^1.6.0",
88
+ "@symbiote-native/react": "^3.3.0",
89
+ "@symbiote-native/solid": "^3.2.0",
90
+ "@symbiote-native/svelte": "^3.2.0",
91
+ "@symbiote-native/vue": "^3.3.0"
92
92
  },
93
93
  "peerDependenciesMeta": {
94
94
  "@symbiote-native/angular": {
@@ -136,13 +136,13 @@
136
136
  "solid-js": "^1.9.14",
137
137
  "svelte": "^5.56.0",
138
138
  "typescript": "~6.0.0",
139
- "@symbiote-native/angular": "3.1.2",
140
- "@symbiote-native/engine": "1.3.1",
141
- "@symbiote-native/react": "3.0.4",
142
- "@symbiote-native/solid": "3.0.4",
143
- "@symbiote-native/svelte": "3.0.4",
144
- "@symbiote-native/test-utils": "0.4.4",
145
- "@symbiote-native/vue": "3.0.4"
139
+ "@symbiote-native/angular": "3.3.0",
140
+ "@symbiote-native/engine": "1.6.0",
141
+ "@symbiote-native/react": "3.3.0",
142
+ "@symbiote-native/solid": "3.2.0",
143
+ "@symbiote-native/svelte": "3.2.0",
144
+ "@symbiote-native/test-utils": "0.4.7",
145
+ "@symbiote-native/vue": "3.3.0"
146
146
  },
147
147
  "scripts": {
148
148
  "typecheck": "tsc --build",