@symbiote-native/file-system 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 +52 -32
  2. package/package.json +15 -15
package/README.md CHANGED
@@ -1,16 +1,19 @@
1
1
  # @symbiote-native/file-system
2
2
 
3
- A wrapper package for [SymbioteNative](../../README.md) that makes
4
- [`expo-file-system`](https://github.com/expo/expo/tree/main/packages/expo-file-system) usable
5
- from **every** adapter — React, Vue, Svelte, Solid, and Angular.
6
-
7
- **Both of upstream's surfaces are ported, matching upstream's own layout.** The default export is
8
- the modern, shared-object API — `File`/`Directory`/`Paths` classes built on JSI shared objects
9
- (`expo-modules-core`'s `SharedObject`), upstream's own default entry as of SDK 54. The legacy,
10
- function-based API (read/write/copy/move/delete, directory listing, disk-space queries, resumable
11
- download/upload, Android Storage Access Framework) is available at the `./legacy` subpath,
12
- reachable in the real upstream package as `expo-file-system/legacy`. See
13
- [Legacy API (`/legacy`)](#legacy-api-legacy) below.
3
+ Read, write, copy, move and download files on the device. One API for every
4
+ [SymbioteNative](../../README.md) adapter (React, Vue, Svelte, Solid and Angular).
5
+
6
+ It wraps [`expo-file-system`](https://github.com/expo/expo/tree/main/packages/expo-file-system) and
7
+ ports both of upstream's surfaces, matching upstream's own layout:
8
+
9
+ - **Default export:** the modern `File` / `Directory` / `Paths` classes, built on JSI shared objects
10
+ (`expo-modules-core`'s `SharedObject`). Upstream's default entry since SDK 54.
11
+ - **`./legacy` subpath:** the function-based API (read/write/copy/move/delete, directory listing,
12
+ disk-space queries, resumable download/upload, Android Storage Access Framework), reachable
13
+ upstream as `expo-file-system/legacy`. See [Legacy API (`/legacy`)](#legacy-api-legacy) below.
14
+
15
+ Which directory? `Paths.document` is for data the user expects to keep; `Paths.cache` is for
16
+ anything you can re-create, and the OS may clear it when storage runs low.
14
17
 
15
18
  ## Install
16
19
 
@@ -26,33 +29,33 @@ npx @symbiote-native/cli new my-app --file-system
26
29
  npx @symbiote-native/cli add --file-system
27
30
  ```
28
31
 
29
- Either way: installs `@symbiote-native/file-system` and wires the native autolinking automatically — see
32
+ Either way: installs `@symbiote-native/file-system` and wires the native autolinking automatically - see
30
33
  [`@symbiote-native/cli`](../cli).
31
34
 
32
35
  <details>
33
- <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>
34
37
 
35
38
  ```bash
36
39
  npm install @symbiote-native/file-system
37
40
  ```
38
41
 
39
42
  `expo-file-system` and `expo-modules-core` come along as regular dependencies, pinned to exact
40
- versions — never install them yourself, and never add the `expo` meta-package to your project.
43
+ versions - never install them yourself, and never add the `expo` meta-package to your project.
41
44
 
42
45
  ## Required one-time step: native autolinking wiring
43
46
 
44
- Same one-time step as every other `expo-modules-core` package this project ships — see
47
+ Same one-time step as every other `expo-modules-core` package this project ships - see
45
48
  [`@symbiote-native/local-auth`'s README](../local-auth/README.md#required-one-time-step-native-autolinking-wiring)
46
49
  and the `symbiote-expo-native-module` project skill.
47
50
 
48
- `native-link.json` carries no `Info.plist` keys or `<application>` attributes — upstream's own
51
+ `native-link.json` carries no `Info.plist` keys or `<application>` attributes - upstream's own
49
52
  config plugin only sets two OPT-IN keys (`LSSupportsOpeningDocumentsInPlace`,
50
53
  `UIFileSharingEnabled`), which an app adds itself only if it wants its Documents directory exposed
51
54
  to the Files app; nothing here needs either by default.
52
55
 
53
56
  </details>
54
57
 
55
- **Android runtime permissions are NOT added automatically, by the CLI or otherwise** — add
58
+ **Android runtime permissions are NOT added automatically, by the CLI or otherwise** - add
56
59
  whichever of these your app actually needs to your own `AndroidManifest.xml`, the same opt-in
57
60
  shape [`@symbiote-native/media-library`](../media-library) uses:
58
61
 
@@ -65,25 +68,25 @@ shape [`@symbiote-native/media-library`](../media-library) uses:
65
68
 
66
69
  `Paths.document`/`Paths.cache` operations and `StorageAccessFramework` (which asks the user to pick
67
70
  a directory at runtime, and never touches the two `EXTERNAL_STORAGE` permissions) both work without
68
- any of these on modern Android — they matter only for direct legacy-path access outside the app
71
+ any of these on modern Android - they matter only for direct legacy-path access outside the app
69
72
  sandbox.
70
73
 
71
74
  ## Shape
72
75
 
73
76
  ```
74
77
  src/next/ File.ts / Directory.ts / Paths.ts / network-tasks.ts (UploadTask/DownloadTask) /
75
- watcher.ts (FileSystemWatcher) / path-utilities.ts / streams.ts / types.ts —
78
+ watcher.ts (FileSystemWatcher) / path-utilities.ts / streams.ts / types.ts -
76
79
  the default, shared-object surface. See "API" below.
77
80
  src/core/ file-system.ts (every legacy function + DownloadResumable/UploadTask +
78
81
  StorageAccessFramework), native-module.ts, types.ts. See "Legacy API" below.
79
- src/angular/ @symbiote-native/file-system/angular — export * from '../next'
82
+ src/angular/ @symbiote-native/file-system/angular - export * from '../next'
80
83
  ```
81
84
 
82
- `./react`, `./vue`, `./svelte`, and `./solid` are `exports`-map aliases straight onto `src/next/`
83
- — every class here carries no children/ref/render fields, so there is nothing to split per
85
+ `./react`, `./vue`, `./svelte`, and `./solid` are `exports`-map aliases straight onto `src/next/`:
86
+ every class here carries no children/ref/render fields, so there is nothing to split per
84
87
  framework. `./angular` stays a physical file/subpath since Angular ships through a separate
85
88
  `ngc`/AOT build (`build-ngc/`). `./legacy` is one subpath shared by every adapter, for the same
86
- reason — plain async functions have no framework-specific shape either.
89
+ reason - plain async functions have no framework-specific shape either.
87
90
 
88
91
  ## Use it
89
92
 
@@ -108,7 +111,7 @@ const downloaded = await File.downloadFileAsync(
108
111
  );
109
112
  ```
110
113
 
111
- Identical import surface on every adapter — `@symbiote-native/file-system/react`, `/vue`,
114
+ Identical import surface on every adapter - `@symbiote-native/file-system/react`, `/vue`,
112
115
  `/svelte`, `/solid`, `/angular` all re-export the same classes.
113
116
 
114
117
  ## API
@@ -176,7 +179,7 @@ static fromSavable(savable): DownloadTask
176
179
 
177
180
  ### Errors
178
181
 
179
- No custom JS error-class hierarchy — every native exception surfaces as an ordinary thrown `Error`
182
+ No custom JS error-class hierarchy - every native exception surfaces as an ordinary thrown `Error`
180
183
  or rejected `Promise`, same as every other native module wrapper in this repo.
181
184
 
182
185
  | Trigger | When |
@@ -185,15 +188,32 @@ or rejected `Promise`, same as every other native module wrapper in this repo.
185
188
  | Reading/writing through a stale or already-closed handle | `IFileSystemHandle` methods throw |
186
189
  | `pickFileAsync`/`pickDirectoryAsync` cancelled by the user | Rejects with an `AbortError` (old-API overload) or resolves `{ canceled: true }` (options-object overload) |
187
190
  | `upload()`/`createUploadTask()`/`createDownloadTask()` aborted via `options.signal` | Rejects with an `AbortError` |
188
- | `.copy()`/`.move()` onto an existing destination without `overwrite: true` | Native `Exception` — destination already exists |
189
- | Any operation on a path outside the app sandbox without permission | Native `Exception` — permission/sandbox violation |
191
+ | `.copy()`/`.move()` onto an existing destination without `overwrite: true` | Native `Exception` - destination already exists |
192
+ | Any operation on a path outside the app sandbox without permission | Native `Exception` - permission/sandbox violation |
193
+
194
+ ## Common questions
195
+
196
+ - **Where does a download go, and why can't the user see it?** The app's private sandbox. For the
197
+ Gallery use [`@symbiote-native/media-library`](../media-library); to let the user keep or send it,
198
+ [`@symbiote-native/sharing`](../sharing); on Android, the legacy `StorageAccessFramework` lets the
199
+ user pick a folder.
200
+ - **Permission denied outside the app's folders.** The classes work inside `Paths.document` and
201
+ `Paths.cache`. Anything else needs the Storage Access Framework (Android).
202
+ - **Document or cache?** `Paths.document` for data to keep; `Paths.cache` for what you can
203
+ re-create. The OS may clear the cache, and you should delete what you no longer need.
204
+ - **`file.create()` throws.** It throws if the file exists or you cannot create it; use
205
+ `file.write()` to replace contents.
206
+
207
+ Sources: [Expo forums thread](https://forums.expo.dev/t/unable-to-download-file-in-expected-location/19632),
208
+ [expo/expo#20298](https://github.com/expo/expo/issues/20298),
209
+ [Expo docs: FileSystem (legacy)](https://docs.expo.dev/versions/latest/sdk/filesystem-legacy/).
190
210
 
191
211
  ## Legacy API (`/legacy`)
192
212
 
193
- Upstream's original function-based surface — plain async functions over `expo-modules-core`
213
+ Upstream's original function-based surface - plain async functions over `expo-modules-core`
194
214
  instead of JSI shared objects. Same install, same autolinking step as above; the native module
195
215
  behind it is a **separate** registration (`ExponentFileSystem`, vs. the modern API's
196
- `FileSystem`) inside the same `expo-file-system` npm dependency — nothing extra to install.
216
+ `FileSystem`) inside the same `expo-file-system` npm dependency - nothing extra to install.
197
217
 
198
218
  ```ts
199
219
  import {
@@ -251,12 +271,12 @@ repo's `I`-prefix convention for exported types (`ts-js-best-practices`).
251
271
 
252
272
  ### Legacy notes
253
273
 
254
- - **`StorageAccessFramework` is Android-only** — every function throws `UnavailabilityError` on iOS,
274
+ - **`StorageAccessFramework` is Android-only** - every function throws `UnavailabilityError` on iOS,
255
275
  matching upstream (there is no SAF equivalent on iOS; use the ordinary `document`/`cacheDirectory`
256
276
  functions there instead).
257
- - **`getContentUriAsync` is Android-only** — on iOS it resolves to the input `fileUri` unchanged,
277
+ - **`getContentUriAsync` is Android-only** - on iOS it resolves to the input `fileUri` unchanged,
258
278
  matching upstream's own platform branch, rather than throwing.
259
- - **Progress callbacks fire only while a task is subscribed** — `DownloadResumable`/`UploadTask`
279
+ - **Progress callbacks fire only while a task is subscribed** - `DownloadResumable`/`UploadTask`
260
280
  add their native event listener only for the duration of the in-flight call
261
281
  (`downloadAsync`/`uploadAsync`/`resumeAsync`), removing it as soon as the promise settles, exactly
262
282
  as upstream does.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/file-system",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "expo-file-system wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. Matches upstream's own layout: the modern JSI shared-object File/Directory/Paths API (including upload/download tasks and filesystem watching) at the package root, and the legacy function-based API (read/write/copy/move/delete, directory listing, disk-space queries, resumable download/upload, Android Storage Access Framework) at the ./legacy subpath. See the module's own README.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -74,7 +74,7 @@
74
74
  },
75
75
  "dependencies": {
76
76
  "expo-file-system": "57.0.6",
77
- "expo-modules-core": "57.0.5"
77
+ "expo-modules-core": "57.0.20"
78
78
  },
79
79
  "peerDependencies": {
80
80
  "@angular/core": ">=20",
@@ -84,12 +84,12 @@
84
84
  "solid-js": ">=1.9.0",
85
85
  "svelte": ">=5.56.0",
86
86
  "vue": ">=3.5.0",
87
- "@symbiote-native/angular": "^3.1.2",
88
- "@symbiote-native/engine": "^1.3.1",
89
- "@symbiote-native/react": "^3.0.4",
90
- "@symbiote-native/solid": "^3.0.4",
91
- "@symbiote-native/svelte": "^3.0.4",
92
- "@symbiote-native/vue": "^3.0.4"
87
+ "@symbiote-native/angular": "^3.3.0",
88
+ "@symbiote-native/engine": "^1.6.0",
89
+ "@symbiote-native/react": "^3.3.0",
90
+ "@symbiote-native/solid": "^3.2.0",
91
+ "@symbiote-native/svelte": "^3.2.0",
92
+ "@symbiote-native/vue": "^3.3.0"
93
93
  },
94
94
  "peerDependenciesMeta": {
95
95
  "@symbiote-native/angular": {
@@ -137,13 +137,13 @@
137
137
  "solid-js": "^1.9.14",
138
138
  "svelte": "^5.56.0",
139
139
  "typescript": "~6.0.0",
140
- "@symbiote-native/angular": "3.1.2",
141
- "@symbiote-native/engine": "1.3.1",
142
- "@symbiote-native/react": "3.0.4",
143
- "@symbiote-native/solid": "3.0.4",
144
- "@symbiote-native/svelte": "3.0.4",
145
- "@symbiote-native/test-utils": "0.4.4",
146
- "@symbiote-native/vue": "3.0.4"
140
+ "@symbiote-native/angular": "3.3.0",
141
+ "@symbiote-native/engine": "1.6.0",
142
+ "@symbiote-native/react": "3.3.0",
143
+ "@symbiote-native/solid": "3.2.0",
144
+ "@symbiote-native/svelte": "3.2.0",
145
+ "@symbiote-native/test-utils": "0.4.7",
146
+ "@symbiote-native/vue": "3.3.0"
147
147
  },
148
148
  "scripts": {
149
149
  "typecheck": "tsc --build",