@swiftbrowser/native 0.19.0 → 0.21.0

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 (64) hide show
  1. package/README.md +34 -11
  2. package/dist/blob.d.ts +85 -11
  3. package/dist/blob.d.ts.map +1 -1
  4. package/dist/blob.js +184 -34
  5. package/dist/blob.js.map +1 -1
  6. package/dist/bridge.d.ts +33 -2
  7. package/dist/bridge.d.ts.map +1 -1
  8. package/dist/bridge.js.map +1 -1
  9. package/dist/fetch.d.ts +19 -11
  10. package/dist/fetch.d.ts.map +1 -1
  11. package/dist/fetch.js +105 -41
  12. package/dist/fetch.js.map +1 -1
  13. package/dist/hostRequests.d.ts +3 -1
  14. package/dist/hostRequests.d.ts.map +1 -1
  15. package/dist/hostRequests.js +47 -6
  16. package/dist/hostRequests.js.map +1 -1
  17. package/dist/index.d.ts +1 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -2
  20. package/dist/index.js.map +1 -1
  21. package/dist/runtime.js +1 -1
  22. package/dist/runtime.js.map +1 -1
  23. package/dist/webSocket.d.ts.map +1 -1
  24. package/dist/webSocket.js +13 -1
  25. package/dist/webSocket.js.map +1 -1
  26. package/package.json +3 -3
  27. package/src/blob.ts +215 -34
  28. package/src/bridge.ts +27 -2
  29. package/src/fetch.ts +99 -41
  30. package/src/hostRequests.ts +62 -8
  31. package/src/index.ts +1 -2
  32. package/src/runtime.ts +1 -1
  33. package/src/webSocket.ts +10 -1
  34. package/swift/Packages/SwiftBrowserDSP/Sources/SwiftBrowserDSP/ProgramNode.swift +122 -19
  35. package/swift/Packages/SwiftBrowserDSP/Sources/SwiftBrowserDSP/ScopeView.swift +79 -0
  36. package/swift/Packages/SwiftBrowserDSP/Sources/SwiftBrowserDSPCore/Machine.swift +1247 -209
  37. package/swift/Packages/SwiftBrowserDSP/Sources/SwiftBrowserDSPCore/Program.swift +314 -19
  38. package/swift/Packages/SwiftBrowserShader/Package.swift +31 -0
  39. package/swift/Packages/SwiftBrowserShader/README.md +45 -0
  40. package/swift/Packages/SwiftBrowserShader/Sources/SwiftBrowserShader/ShaderRenderer.swift +103 -0
  41. package/swift/Packages/SwiftBrowserShader/Sources/SwiftBrowserShader/ShaderView.swift +168 -0
  42. package/swift/Packages/SwiftBrowserShader/Sources/SwiftBrowserShaderCore/ShaderProps.swift +120 -0
  43. package/swift/Sources/SwiftBrowserNative/Host/BodyStream.swift +166 -0
  44. package/swift/Sources/SwiftBrowserNative/Host/FilesBridge.swift +141 -7
  45. package/swift/Sources/SwiftBrowserNative/Host/HostBridge.swift +47 -1
  46. package/swift/Sources/SwiftBrowserNative/Host/HostRequestBridge.swift +98 -29
  47. package/swift/Sources/SwiftBrowserNative/Runtime/NativeFunctions.swift +1 -1
  48. package/swift/Sources/SwiftBrowserNative/Runtime/ViewRegistry.swift +57 -0
  49. package/swift/Sources/SwiftBrowserNative/Views/ElementView.swift +11 -7
  50. package/swift/Sources/SwiftBrowserNative/Views/Kinds/Drawing.swift +378 -0
  51. package/swift/Sources/SwiftBrowserNative/Views/Kinds/Navigation.swift +15 -10
  52. package/swift/Sources/SwiftBrowserNative/Views/Kinds/PopTap.swift +31 -28
  53. package/swift/Sources/SwiftBrowserNative/Views/StyleModifier.swift +142 -0
  54. package/swift/Sources/SwiftBrowserProtocol/Drawing.swift +306 -0
  55. package/swift/Sources/SwiftBrowserProtocol/Props.swift +5 -2
  56. package/swift/Sources/SwiftBrowserProtocol/RendererEvent.swift +24 -3
  57. package/swift/Sources/SwiftBrowserProtocol/Style.swift +87 -0
  58. package/wasm/SwiftBrowserNative.wasm +2 -2
  59. package/dist/native.d.ts +0 -19
  60. package/dist/native.d.ts.map +0 -1
  61. package/dist/native.js +0 -17
  62. package/dist/native.js.map +0 -1
  63. package/src/native.ts +0 -35
  64. package/swift/Sources/SwiftBrowserNative/Runtime/NativeRegistry.swift +0 -53
package/README.md CHANGED
@@ -97,9 +97,16 @@ There is no `window` and no `document`. Code that checks for them takes its
97
97
  headless path, which is right here; `@swiftbrowser/react`'s `Host` (React DOM
98
98
  inside the tree) renders nothing, as `react-dom` is aliased to a stub.
99
99
 
100
- `fetch` sends the request over the bridge and `URLSession` performs it;
101
- bodies are whole (no streams), and may be a `Blob` or a `FormData` (sent as
102
- multipart: a file upload works as written for the page). `URL` is a small
100
+ `fetch` sends the request over the bridge and `URLSession` performs it. A
101
+ body may be a `Blob` or a `FormData` (sent as multipart: a file upload works
102
+ as written for the page), and one holding picked or dropped files still on
103
+ disk (the files themselves, their slices, a `Blob` built from slices of
104
+ several, a form with them) is streamed from disk: the body goes to the host
105
+ as parts, bytes beside the request and ranges of files, and an `InputStream`
106
+ reads them in order as the request sends, so a 2 GB upload holds nothing in
107
+ memory; a host before 0.20 reads the files first. Responses are read whole
108
+ (`response.body` is null; `arrayBuffer()`, `text()`, `json()`, `blob()`).
109
+ An `AbortController`'s abort cancels the task (`fetchCancel`). `URL` is a small
103
110
  parser, enough for absolute and relative URLs and query strings, not the
104
111
  whole WHATWG algorithm; `URL.createObjectURL` gives a `data:` URL. `WebSocket`
105
112
  runs on `URLSessionWebSocketTask`, `crypto.subtle` digests (SHA-1 to
@@ -116,11 +123,15 @@ background, where the system owns the screen, and holds again on return).
116
123
  Apple sheet (`ASAuthorizationController`, with the app's
117
124
  `com.apple.developer.applesignin` entitlement) and answer the credential;
118
125
  `appleCredentialState` asks the provider.
119
- `fileManager` reaches the app's sandbox through `files` requests, and its
126
+ `fileManager` reaches the app's sandbox through `files` requests (a
127
+ `range` read is `FileHandle`'s seek and read, so a large file goes a piece
128
+ at a time; a picked or dropped file written is copied on disk, `importItem`,
129
+ never through the bridge), and its
120
130
  iCloud Drive container (`iCloudDirectory()`) where the app has the
121
131
  entitlement: the container's files are read and written under file
122
132
  coordination, downloaded first when another device wrote them, and their
123
- changes come to `__sbFilesChanged` for `fileManager.watch`.
133
+ changes come to `__sbFilesChanged` for `fileManager.watch`, as the app's
134
+ own writes do.
124
135
  `navigator.geolocation` asks `CLLocationManager`: `getCurrentPosition` for
125
136
  one fix, `watchPosition` for every fix until `clearWatch`, with the API's
126
137
  `GeolocationPositionError` codes (the first ask prompts the viewer; the
@@ -271,7 +282,15 @@ the host answers instead, with `UIActivityViewController`, the photo picker
271
282
  to Files), `UIPasteboard` and `UIColorPickerViewController`.
272
283
  Nothing to write: `run` fills the web renderer's environment with what the
273
284
  page has nothing for, so a screen written for the page shares and picks as
274
- it did. Picked files are `File`s with their bytes.
285
+ it did. A picked file is a `LazyFile`: a `File` whose name, type and size
286
+ are known and whose bytes stay on disk (a document in the app's tmp, a
287
+ photo copied there, a folder opened in place with its security scope kept)
288
+ until `arrayBuffer()`, `text()` or a `slice` reads them by range through the
289
+ files bridge; `fileManager.write` copies it, a `fetch` body or `FormData`
290
+ streams it from disk, `ShareLink` and `fileExporter` copy it. Files dropped on a
291
+ `dropDestination` from another app arrive the same way, a dropped folder's
292
+ named by their paths in it. The app keeps them readable until it asks the
293
+ host to forget them (`files` `release`, or the next folder pick).
275
294
 
276
295
  ```ts
277
296
  import { webAuthenticate, secureStorage } from '@swiftbrowser/native';
@@ -368,24 +387,28 @@ the site: a `.symbolset` holding any SVG draws as a symbol there), and
368
387
  `--worker <name>=<entry>` (repeatable) for the app's workers, published
369
388
  beside the bundle for the page's `Worker`.
370
389
 
371
- ## The escape hatch
390
+ ## Registered views
372
391
 
373
392
  ```tsx
374
- import { Native } from '@swiftbrowser/native';
393
+ import { RegisteredView } from '@swiftbrowser/react';
375
394
 
376
- <Native name="MapView" props={{ region }} onEvent={(value) => console.log('map said', value)}>
395
+ <RegisteredView name="MapView" props={{ region }} onEvent={(value) => console.log('map said', value)}>
377
396
  <Text>Children are SwiftUI views inside the native view</Text>
378
- </Native>
397
+ </RegisteredView>
379
398
  ```
380
399
 
381
400
  The Swift app registers the view once:
382
401
 
383
402
  ```swift
384
- NativeRegistry.register("MapView") { context in
403
+ ViewRegistry.register("MapView") { context in
385
404
  MapView(region: context.props["region"]) { context.send(["tapped": true]) }
386
405
  }
387
406
  ```
388
407
 
408
+ and a page can register its own element under the same name
409
+ (`ViewRegistry.register('MapView', (context) => ({ element, update, dispose }))`,
410
+ also from @swiftbrowser/react), so the same element draws on both.
411
+
389
412
  Swift that is not a view registers as a function, before the bundle loads
390
413
  (`swiftbrowser native init` writes an `ios/NativeFunctions.swift` for them):
391
414
 
package/dist/blob.d.ts CHANGED
@@ -1,25 +1,49 @@
1
1
  /**
2
2
  * `Blob`, `File` and `FormData` for the native app: bytes with a type, a
3
- * named one, and a form whose entries `fetch` sends as multipart. A body is
4
- * still whole (no streams); `URL.createObjectURL` gives a `data:` URL, which
5
- * the host's image loader and `URLSession` both read, and
6
- * `revokeObjectURL` has nothing to free.
3
+ * named one, and a form whose entries `fetch` sends as multipart. A blob is
4
+ * a list of parts, each bytes in memory or a range of a file on disk (a
5
+ * `LazyFile`, as the pickers and drops answer), so a `Blob` built from
6
+ * picked files' slices holds nothing in memory and `fetch` streams it from
7
+ * disk (fetch.ts). `URL.createObjectURL` gives a `data:` URL, which the
8
+ * host's image loader and `URLSession` both read, and `revokeObjectURL` has
9
+ * nothing to free.
7
10
  */
8
11
  export type BlobPartLike = string | ArrayBuffer | ArrayBufferView | SimpleBlob;
12
+ /** What a blob, and so a request body, is made of: bytes here, or a range of a file on disk. */
13
+ export type BodyPart = {
14
+ bytes: Uint8Array;
15
+ } | {
16
+ file: LazyFile;
17
+ };
9
18
  export interface BlobOptions {
10
19
  type?: string;
11
20
  }
12
21
  export interface FileOptions extends BlobOptions {
13
22
  lastModified?: number;
14
23
  }
15
- /** The browser's `Blob`: bytes and a MIME type. */
24
+ export declare const partSize: (part: BodyPart) => number;
25
+ /** Whether any part is a file on disk, which only an asynchronous read reaches. */
26
+ export declare const partsAreLazy: (parts: readonly BodyPart[]) => boolean;
27
+ /** The parts' bytes, whole: those on disk read through the files bridge. */
28
+ export declare function partsBytes(parts: readonly BodyPart[]): Promise<Uint8Array>;
29
+ /** The browser's `Blob`: parts (bytes, or files on disk) and a MIME type. */
16
30
  export declare class SimpleBlob {
17
- private readonly data;
31
+ private readonly parts_;
32
+ /** The parts joined, once asked for (a blob with nothing on disk). */
33
+ private joined;
18
34
  readonly type: string;
19
35
  constructor(parts?: Iterable<BlobPartLike>, options?: BlobOptions);
36
+ /** A blob straight from parts (a slice). */
37
+ protected static fromParts(parts: BodyPart[], type: string): SimpleBlob;
20
38
  get size(): number;
21
- /** The bytes (a view; callers must not write into it). */
39
+ /** The parts, in order: what a request body sends, each from memory or from disk. */
40
+ parts(): BodyPart[];
41
+ /** Whether any part is still on disk, so `bytes()` cannot answer and `bytesAsync()` reads it. */
42
+ get isLazy(): boolean;
43
+ /** The bytes (a view; callers must not write into it). Throws for a blob holding a file on disk: read it with `bytesAsync`. */
22
44
  bytes(): Uint8Array;
45
+ /** The bytes, the parts on disk read now. */
46
+ bytesAsync(): Promise<Uint8Array>;
23
47
  slice(start?: number, end?: number, contentType?: string): SimpleBlob;
24
48
  arrayBuffer(): Promise<ArrayBuffer>;
25
49
  text(): Promise<string>;
@@ -32,11 +56,49 @@ export declare class SimpleFile extends SimpleBlob {
32
56
  constructor(parts: Iterable<BlobPartLike>, name: string, options?: FileOptions);
33
57
  get [Symbol.toStringTag](): string;
34
58
  }
59
+ /**
60
+ * A file the viewer picked or dropped, still on disk: its name, type and size
61
+ * are known, its bytes are read through the host's files bridge only when
62
+ * asked (`arrayBuffer`, `bytesAsync`, or a `fetch` body), a range at a time
63
+ * for a `slice`, so a large file never sits in memory whole. `fileManager.write`
64
+ * copies one on disk instead of reading it. `bytes()` (synchronous) is not
65
+ * available: it throws, as the bytes are not here.
66
+ */
67
+ export declare class LazyFile extends SimpleFile {
68
+ /** The `file:` URL the host reads it at. */
69
+ readonly url: string;
70
+ /** The range of the file on disk this stands for (`slice` narrows it). */
71
+ readonly start: number;
72
+ readonly end: number;
73
+ private readonly reader;
74
+ constructor(url: string, name: string, size: number, reader: (url: string, start: number, end: number) => Promise<Uint8Array>, options?: FileOptions, range?: {
75
+ start: number;
76
+ end: number;
77
+ });
78
+ /** Whether this is the whole file on disk, not a slice of it. */
79
+ get isWhole(): boolean;
80
+ private sizeOnDisk;
81
+ /** Sets the file's size on disk (the constructor's `size`); the range defaults to all of it. */
82
+ static make(url: string, name: string, size: number, reader: (url: string, start: number, end: number) => Promise<Uint8Array>, options?: FileOptions): LazyFile;
83
+ get size(): number;
84
+ parts(): BodyPart[];
85
+ get isLazy(): boolean;
86
+ bytes(): Uint8Array;
87
+ /** The bytes, read from disk now. */
88
+ bytesAsync(): Promise<Uint8Array>;
89
+ slice(start?: number, end?: number, contentType?: string): LazyFile;
90
+ /** The same file under another name (a form's `filename`), still on disk. */
91
+ renamed(name: string): LazyFile;
92
+ }
93
+ /** A blob's bytes, read from disk where it holds a `LazyFile`. */
94
+ export declare function blobBytes(blob: SimpleBlob): Promise<Uint8Array>;
35
95
  export type FormDataEntryValueLike = string | SimpleFile;
36
96
  /** The browser's `FormData`, as far as a request body needs it. */
37
97
  export declare class SimpleFormData {
38
98
  private entries_;
39
99
  private static value;
100
+ /** Whether an entry is a picked file still on disk (or a blob holding one), which the form's body streams from there. */
101
+ get hasLazyFiles(): boolean;
40
102
  append(name: string, value: unknown, filename?: string): void;
41
103
  set(name: string, value: unknown, filename?: string): void;
42
104
  get(name: string): FormDataEntryValueLike | null;
@@ -50,11 +112,23 @@ export declare class SimpleFormData {
50
112
  [Symbol.iterator](): IterableIterator<[string, FormDataEntryValueLike]>;
51
113
  get [Symbol.toStringTag](): string;
52
114
  }
53
- /** A multipart/form-data body for the form, with the boundary `random` makes unique. */
54
- export declare function encodeMultipart(form: SimpleFormData, random: (count: number) => Uint8Array): {
55
- bytes: Uint8Array;
115
+ /** The boundary of a multipart body, unique by `random`'s bytes. */
116
+ export declare function multipartBoundary(random: (count: number) => Uint8Array): string;
117
+ /**
118
+ * A multipart/form-data body for the form, with the boundary `random` makes
119
+ * unique, as parts: the heads and the fields in memory, a file still on disk
120
+ * as the range of it (`fetch` streams those from disk, or reads them first
121
+ * for a host that cannot).
122
+ */
123
+ export declare function encodeMultipart(form: SimpleFormData, random: (count: number) => Uint8Array, boundary?: string): {
124
+ parts: BodyPart[];
56
125
  contentType: string;
57
126
  };
58
- /** `URL.createObjectURL`: a `data:` URL holding the blob. */
127
+ /** `encodeMultipart` with the body whole: a form's files on disk are read first. */
128
+ export declare function encodeMultipartAsync(form: SimpleFormData, random: (count: number) => Uint8Array, boundary?: string): Promise<{
129
+ bytes: Uint8Array;
130
+ contentType: string;
131
+ }>;
132
+ /** `URL.createObjectURL`: a `data:` URL holding the blob; a picked file still on disk is its own `file:` URL. */
59
133
  export declare function objectURL(blob: SimpleBlob): string;
60
134
  //# sourceMappingURL=blob.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,GAAG,eAAe,GAAG,UAAU,CAAC;AAE/E,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAqBD,mDAAmD;AACnD,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,KAAK,GAAE,QAAQ,CAAC,YAAY,CAAM,EAAE,OAAO,GAAE,WAAgB;IAOzE,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,0DAA0D;IAC1D,KAAK,IAAI,UAAU;IAInB,KAAK,CAAC,KAAK,SAAI,EAAE,GAAG,SAAY,EAAE,WAAW,SAAK,GAAG,UAAU;IAMzD,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAInC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAEjC;CACF;AAED,kDAAkD;AAClD,qBAAa,UAAW,SAAQ,UAAU;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAElB,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IAMlF,IAAa,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAE1C;CACF;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEzD,mEAAmE;AACnE,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAA0C;IAE1D,OAAO,CAAC,MAAM,CAAC,KAAK;IAQpB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAI7D,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAY1D,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI;IAIhD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,EAAE;IAI9C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIzB,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAI7D,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAIhC,MAAM,IAAI,gBAAgB,CAAC,sBAAsB,CAAC;IAInD,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;IAIpG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAIvE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAEjC;CACF;AAED,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,UAAU,GAAG;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAavI;AAED,6DAA6D;AAC7D,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAElD"}
1
+ {"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"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"}
package/dist/blob.js CHANGED
@@ -1,21 +1,35 @@
1
1
  /**
2
2
  * `Blob`, `File` and `FormData` for the native app: bytes with a type, a
3
- * named one, and a form whose entries `fetch` sends as multipart. A body is
4
- * still whole (no streams); `URL.createObjectURL` gives a `data:` URL, which
5
- * the host's image loader and `URLSession` both read, and
6
- * `revokeObjectURL` has nothing to free.
3
+ * named one, and a form whose entries `fetch` sends as multipart. A blob is
4
+ * a list of parts, each bytes in memory or a range of a file on disk (a
5
+ * `LazyFile`, as the pickers and drops answer), so a `Blob` built from
6
+ * picked files' slices holds nothing in memory and `fetch` streams it from
7
+ * disk (fetch.ts). `URL.createObjectURL` gives a `data:` URL, which the
8
+ * host's image loader and `URLSession` both read, and `revokeObjectURL` has
9
+ * nothing to free.
7
10
  */
8
11
  import { base64Encode, utf8Decode, utf8Encode } from './encoding';
9
- function partBytes(part) {
12
+ /** A constructor part as body parts: a blob's own parts are taken as they are (a file on disk stays there). */
13
+ function toParts(part) {
10
14
  if (typeof part === 'string')
11
- return utf8Encode(part);
15
+ return [{ bytes: utf8Encode(part) }];
12
16
  if (part instanceof SimpleBlob)
13
- return part.bytes();
17
+ return part.parts();
14
18
  if (part instanceof ArrayBuffer)
15
- return new Uint8Array(part.slice(0));
19
+ return [{ bytes: new Uint8Array(part.slice(0)) }];
16
20
  if (ArrayBuffer.isView(part))
17
- return new Uint8Array(part.buffer.slice(part.byteOffset, part.byteOffset + part.byteLength));
18
- return utf8Encode(String(part));
21
+ return [{ bytes: new Uint8Array(part.buffer.slice(part.byteOffset, part.byteOffset + part.byteLength)) }];
22
+ return [{ bytes: utf8Encode(String(part)) }];
23
+ }
24
+ export const partSize = (part) => ('bytes' in part ? part.bytes.byteLength : part.file.size);
25
+ /** Whether any part is a file on disk, which only an asynchronous read reaches. */
26
+ export const partsAreLazy = (parts) => parts.some((part) => 'file' in part);
27
+ /** The parts' bytes, whole: those on disk read through the files bridge. */
28
+ export async function partsBytes(parts) {
29
+ const read = [];
30
+ for (const part of parts)
31
+ read.push('bytes' in part ? part.bytes : await part.file.bytesAsync());
32
+ return concat(read);
19
33
  }
20
34
  function concat(parts) {
21
35
  const total = parts.reduce((sum, part) => sum + part.byteLength, 0);
@@ -27,33 +41,71 @@ function concat(parts) {
27
41
  }
28
42
  return out;
29
43
  }
30
- /** The browser's `Blob`: bytes and a MIME type. */
44
+ /** The browser's `Blob`: parts (bytes, or files on disk) and a MIME type. */
31
45
  export class SimpleBlob {
32
- data;
46
+ parts_;
47
+ /** The parts joined, once asked for (a blob with nothing on disk). */
48
+ joined = null;
33
49
  type;
34
50
  constructor(parts = [], options = {}) {
35
- this.data = concat([...parts].map(partBytes));
51
+ this.parts_ = [...parts].flatMap(toParts);
36
52
  // As the browser does: lowercased, and empty when it is not printable ASCII.
37
53
  const type = options.type ?? '';
38
54
  this.type = /^[\x20-\x7e]*$/.test(type) ? type.toLowerCase() : '';
39
55
  }
56
+ /** A blob straight from parts (a slice). */
57
+ static fromParts(parts, type) {
58
+ const blob = new SimpleBlob([], { type });
59
+ blob.parts_.push(...parts);
60
+ return blob;
61
+ }
40
62
  get size() {
41
- return this.data.byteLength;
63
+ return this.parts_.reduce((sum, part) => sum + partSize(part), 0);
64
+ }
65
+ /** The parts, in order: what a request body sends, each from memory or from disk. */
66
+ parts() {
67
+ return [...this.parts_];
68
+ }
69
+ /** Whether any part is still on disk, so `bytes()` cannot answer and `bytesAsync()` reads it. */
70
+ get isLazy() {
71
+ return partsAreLazy(this.parts_);
42
72
  }
43
- /** The bytes (a view; callers must not write into it). */
73
+ /** The bytes (a view; callers must not write into it). Throws for a blob holding a file on disk: read it with `bytesAsync`. */
44
74
  bytes() {
45
- return this.data;
75
+ if (this.isLazy)
76
+ throw new Error('unsupported: the blob holds a picked file, which is read asynchronously (arrayBuffer); it is not in memory');
77
+ if (!this.joined)
78
+ this.joined = this.parts_.length === 1 && 'bytes' in this.parts_[0] ? this.parts_[0].bytes : concat(this.parts_.map((part) => ('bytes' in part ? part.bytes : new Uint8Array(0))));
79
+ return this.joined;
80
+ }
81
+ /** The bytes, the parts on disk read now. */
82
+ async bytesAsync() {
83
+ return this.isLazy ? partsBytes(this.parts_) : this.bytes();
46
84
  }
47
85
  slice(start = 0, end = this.size, contentType = '') {
48
- const from = start < 0 ? Math.max(this.size + start, 0) : Math.min(start, this.size);
49
- const to = end < 0 ? Math.max(this.size + end, 0) : Math.min(end, this.size);
50
- return new SimpleBlob([this.data.subarray(from, Math.max(from, to))], { type: contentType });
86
+ const size = this.size;
87
+ const from = start < 0 ? Math.max(size + start, 0) : Math.min(start, size);
88
+ const to = Math.max(from, end < 0 ? Math.max(size + end, 0) : Math.min(end, size));
89
+ const out = [];
90
+ let at = 0;
91
+ for (const part of this.parts_) {
92
+ const length = partSize(part);
93
+ const partStart = at;
94
+ at += length;
95
+ if (at <= from || partStart >= to)
96
+ continue;
97
+ const a = Math.max(from, partStart) - partStart;
98
+ const b = Math.min(to, at) - partStart;
99
+ out.push('bytes' in part ? { bytes: part.bytes.subarray(a, b) } : { file: part.file.slice(a, b) });
100
+ }
101
+ return SimpleBlob.fromParts(out, contentType);
51
102
  }
52
103
  async arrayBuffer() {
53
- return this.data.buffer.slice(this.data.byteOffset, this.data.byteOffset + this.data.byteLength);
104
+ const bytes = await this.bytesAsync();
105
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
54
106
  }
55
107
  async text() {
56
- return utf8Decode(this.data);
108
+ return utf8Decode(await this.bytesAsync());
57
109
  }
58
110
  get [Symbol.toStringTag]() {
59
111
  return 'Blob';
@@ -72,16 +124,93 @@ export class SimpleFile extends SimpleBlob {
72
124
  return 'File';
73
125
  }
74
126
  }
127
+ /**
128
+ * A file the viewer picked or dropped, still on disk: its name, type and size
129
+ * are known, its bytes are read through the host's files bridge only when
130
+ * asked (`arrayBuffer`, `bytesAsync`, or a `fetch` body), a range at a time
131
+ * for a `slice`, so a large file never sits in memory whole. `fileManager.write`
132
+ * copies one on disk instead of reading it. `bytes()` (synchronous) is not
133
+ * available: it throws, as the bytes are not here.
134
+ */
135
+ export class LazyFile extends SimpleFile {
136
+ /** The `file:` URL the host reads it at. */
137
+ url;
138
+ /** The range of the file on disk this stands for (`slice` narrows it). */
139
+ start;
140
+ end;
141
+ reader;
142
+ constructor(url, name, size, reader, options = {}, range = { start: 0, end: size }) {
143
+ super([], name, options);
144
+ this.url = url;
145
+ this.reader = reader;
146
+ this.start = range.start;
147
+ this.end = range.end;
148
+ }
149
+ /** Whether this is the whole file on disk, not a slice of it. */
150
+ get isWhole() {
151
+ return this.start === 0 && this.end === this.sizeOnDisk;
152
+ }
153
+ sizeOnDisk = 0;
154
+ /** Sets the file's size on disk (the constructor's `size`); the range defaults to all of it. */
155
+ static make(url, name, size, reader, options = {}) {
156
+ const file = new LazyFile(url, name, size, reader, options);
157
+ file.sizeOnDisk = size;
158
+ return file;
159
+ }
160
+ get size() {
161
+ return this.end - this.start;
162
+ }
163
+ parts() {
164
+ return [{ file: this }];
165
+ }
166
+ get isLazy() {
167
+ return true;
168
+ }
169
+ bytes() {
170
+ throw new Error('unsupported: a picked file is read asynchronously (arrayBuffer); it is not in memory');
171
+ }
172
+ /** The bytes, read from disk now. */
173
+ async bytesAsync() {
174
+ return this.reader(this.url, this.start, this.end);
175
+ }
176
+ slice(start = 0, end = this.size, contentType = '') {
177
+ const size = this.size;
178
+ const from = start < 0 ? Math.max(size + start, 0) : Math.min(start, size);
179
+ const to = end < 0 ? Math.max(size + end, 0) : Math.min(end, size);
180
+ const sliced = new LazyFile(this.url, this.name, this.sizeOnDisk, this.reader, { type: contentType, lastModified: this.lastModified }, {
181
+ start: this.start + from,
182
+ end: this.start + Math.max(from, to),
183
+ });
184
+ sliced.sizeOnDisk = this.sizeOnDisk;
185
+ return sliced;
186
+ }
187
+ /** The same file under another name (a form's `filename`), still on disk. */
188
+ renamed(name) {
189
+ const copy = new LazyFile(this.url, name, this.sizeOnDisk, this.reader, { type: this.type, lastModified: this.lastModified }, { start: this.start, end: this.end });
190
+ copy.sizeOnDisk = this.sizeOnDisk;
191
+ return copy;
192
+ }
193
+ }
194
+ /** A blob's bytes, read from disk where it holds a `LazyFile`. */
195
+ export async function blobBytes(blob) {
196
+ return blob.bytesAsync();
197
+ }
75
198
  /** The browser's `FormData`, as far as a request body needs it. */
76
199
  export class SimpleFormData {
77
200
  entries_ = [];
78
201
  static value(value, filename) {
79
202
  if (value instanceof SimpleBlob) {
80
203
  const name = filename ?? (value instanceof SimpleFile ? value.name : 'blob');
204
+ if (value instanceof LazyFile)
205
+ return filename === undefined ? value : value.renamed(filename);
81
206
  return value instanceof SimpleFile && filename === undefined ? value : new SimpleFile([value], name, { type: value.type });
82
207
  }
83
208
  return String(value);
84
209
  }
210
+ /** Whether an entry is a picked file still on disk (or a blob holding one), which the form's body streams from there. */
211
+ get hasLazyFiles() {
212
+ return this.entries_.some(([, value]) => typeof value !== 'string' && value.isLazy);
213
+ }
85
214
  append(name, value, filename) {
86
215
  this.entries_.push([String(name), SimpleFormData.value(value, filename)]);
87
216
  }
@@ -130,24 +259,45 @@ export class SimpleFormData {
130
259
  return 'FormData';
131
260
  }
132
261
  }
133
- /** A multipart/form-data body for the form, with the boundary `random` makes unique. */
134
- export function encodeMultipart(form, random) {
135
- const boundary = `----SwiftBrowserFormBoundary${Array.from(random(16), (byte) => byte.toString(16).padStart(2, '0')).join('')}`;
262
+ /** The boundary of a multipart body, unique by `random`'s bytes. */
263
+ export function multipartBoundary(random) {
264
+ return `----SwiftBrowserFormBoundary${Array.from(random(16), (byte) => byte.toString(16).padStart(2, '0')).join('')}`;
265
+ }
266
+ function multipartHead(boundary, name, value) {
136
267
  const escape = (text) => text.replace(/\r/g, '%0D').replace(/\n/g, '%0A').replace(/"/g, '%22');
268
+ const head = [`--${boundary}`, `Content-Disposition: form-data; name="${escape(name)}"` + (typeof value === 'string' ? '' : `; filename="${escape(value.name)}"`)];
269
+ if (typeof value !== 'string')
270
+ head.push(`Content-Type: ${value.type || 'application/octet-stream'}`);
271
+ return utf8Encode(`${head.join('\r\n')}\r\n\r\n`);
272
+ }
273
+ /**
274
+ * A multipart/form-data body for the form, with the boundary `random` makes
275
+ * unique, as parts: the heads and the fields in memory, a file still on disk
276
+ * as the range of it (`fetch` streams those from disk, or reads them first
277
+ * for a host that cannot).
278
+ */
279
+ export function encodeMultipart(form, random, boundary = multipartBoundary(random)) {
137
280
  const parts = [];
138
281
  for (const [name, value] of form.entries()) {
139
- const head = [`--${boundary}`, `Content-Disposition: form-data; name="${escape(name)}"` + (typeof value === 'string' ? '' : `; filename="${escape(value.name)}"`)];
140
- if (typeof value !== 'string')
141
- head.push(`Content-Type: ${value.type || 'application/octet-stream'}`);
142
- parts.push(utf8Encode(`${head.join('\r\n')}\r\n\r\n`));
143
- parts.push(typeof value === 'string' ? utf8Encode(value) : value.bytes());
144
- parts.push(utf8Encode('\r\n'));
145
- }
146
- parts.push(utf8Encode(`--${boundary}--\r\n`));
147
- return { bytes: concat(parts), contentType: `multipart/form-data; boundary=${boundary}` };
282
+ parts.push({ bytes: multipartHead(boundary, name, value) });
283
+ if (typeof value === 'string')
284
+ parts.push({ bytes: utf8Encode(value) });
285
+ else
286
+ parts.push(...value.parts());
287
+ parts.push({ bytes: utf8Encode('\r\n') });
288
+ }
289
+ parts.push({ bytes: utf8Encode(`--${boundary}--\r\n`) });
290
+ return { parts, contentType: `multipart/form-data; boundary=${boundary}` };
291
+ }
292
+ /** `encodeMultipart` with the body whole: a form's files on disk are read first. */
293
+ export async function encodeMultipartAsync(form, random, boundary = multipartBoundary(random)) {
294
+ const { parts, contentType } = encodeMultipart(form, random, boundary);
295
+ return { bytes: await partsBytes(parts), contentType };
148
296
  }
149
- /** `URL.createObjectURL`: a `data:` URL holding the blob. */
297
+ /** `URL.createObjectURL`: a `data:` URL holding the blob; a picked file still on disk is its own `file:` URL. */
150
298
  export function objectURL(blob) {
299
+ if (blob instanceof LazyFile && blob.isWhole)
300
+ return blob.url;
151
301
  return `data:${blob.type || 'application/octet-stream'};base64,${base64Encode(blob.bytes())}`;
152
302
  }
153
303
  //# sourceMappingURL=blob.js.map
package/dist/blob.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"blob.js","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"blob.js","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAelE,+GAA+G;AAC/G,SAAS,OAAO,CAAC,IAAkB;IACjC,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnE,IAAI,IAAI,YAAY,UAAU;QAAE,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;IACpD,IAAI,IAAI,YAAY,WAAW;QAAE,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACnF,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC;IACxI,OAAO,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAc,EAAU,EAAE,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAE/G,mFAAmF;AACnF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAA0B,EAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;AAE1G,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAA0B;IACzD,MAAM,IAAI,GAAiB,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACjG,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,MAAM,CAAC,KAAmB;IACjC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtB,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC;IAC5B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6EAA6E;AAC7E,MAAM,OAAO,UAAU;IACJ,MAAM,CAAa;IACpC,sEAAsE;IAC9D,MAAM,GAAsB,IAAI,CAAC;IAChC,IAAI,CAAS;IAEtB,YAAY,QAAgC,EAAE,EAAE,UAAuB,EAAE;QACvE,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1C,6EAA6E;QAC7E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,CAAC;IAED,4CAA4C;IAClC,MAAM,CAAC,SAAS,CAAC,KAAiB,EAAE,IAAY;QACxD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,qFAAqF;IACrF,KAAK;QACH,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,iGAAiG;IACjG,IAAI,MAAM;QACR,OAAO,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,+HAA+H;IAC/H,KAAK;QACH,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4GAA4G,CAAC,CAAC;QAC/I,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtM,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,6CAA6C;IAC7C,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,EAAE;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3E,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QACnF,MAAM,GAAG,GAAe,EAAE,CAAC;QAC3B,IAAI,EAAE,GAAG,CAAC,CAAC;QACX,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC9B,MAAM,SAAS,GAAG,EAAE,CAAC;YACrB,EAAE,IAAI,MAAM,CAAC;YACb,IAAI,EAAE,IAAI,IAAI,IAAI,SAAS,IAAI,EAAE;gBAAE,SAAS;YAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC;YAChD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;YACvC,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACrG,CAAC;QACD,OAAO,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAgB,CAAC;IAClG,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,UAAU,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,kDAAkD;AAClD,MAAM,OAAO,UAAW,SAAQ,UAAU;IAC/B,IAAI,CAAS;IACb,YAAY,CAAS;IAE9B,YAAY,KAA6B,EAAE,IAAY,EAAE,UAAuB,EAAE;QAChF,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACzD,CAAC;IAED,IAAa,CAAC,MAAM,CAAC,WAAW,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,QAAS,SAAQ,UAAU;IACtC,4CAA4C;IACnC,GAAG,CAAS;IACrB,0EAA0E;IACjE,KAAK,CAAS;IACd,GAAG,CAAS;IACJ,MAAM,CAAmE;IAE1F,YACE,GAAW,EACX,IAAY,EACZ,IAAY,EACZ,MAAwE,EACxE,UAAuB,EAAE,EACzB,QAAwC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE;QAE/D,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACzB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACvB,CAAC;IAED,iEAAiE;IACjE,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,UAAU,CAAC;IAC1D,CAAC;IAEO,UAAU,GAAG,CAAC,CAAC;IAEvB,gGAAgG;IAChG,MAAM,CAAC,IAAI,CAAC,GAAW,EAAE,IAAY,EAAE,IAAY,EAAE,MAAwE,EAAE,UAAuB,EAAE;QACtJ,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC5D,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAa,IAAI;QACf,OAAO,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC;IAC/B,CAAC;IAEQ,KAAK;QACZ,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1B,CAAC;IAED,IAAa,MAAM;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAEQ,KAAK;QACZ,MAAM,IAAI,KAAK,CAAC,sFAAsF,CAAC,CAAC;IAC1G,CAAC;IAED,qCAAqC;IAC5B,KAAK,CAAC,UAAU;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC;IAEQ,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,EAAE;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3E,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE;YACrI,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI;YACxB,GAAG,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;SACrC,CAAC,CAAC;QACH,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACpC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,6EAA6E;IAC7E,OAAO,CAAC,IAAY;QAClB,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACpK,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;CAEF;AAED,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAgB;IAC9C,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;AAC3B,CAAC;AAID,mEAAmE;AACnE,MAAM,OAAO,cAAc;IACjB,QAAQ,GAAuC,EAAE,CAAC;IAElD,MAAM,CAAC,KAAK,CAAC,KAAc,EAAE,QAAiB;QACpD,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,QAAQ,IAAI,CAAC,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC7E,IAAI,KAAK,YAAY,QAAQ;gBAAE,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC/F,OAAO,KAAK,YAAY,UAAU,IAAI,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7H,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,yHAAyH;IACzH,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,KAAc,EAAE,QAAiB;QACpD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,GAAG,CAAC,IAAY,EAAE,KAAc,EAAE,QAAiB;QACjD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,KAAK,GAAqC,CAAC,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC7F,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,SAAS,KAAK,GAAG,CAAC,CAAC;QAC1E,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,KAAK,IAAI,SAAS,KAAK,GAAG,CAAC,CAAC;QACzG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;IAC/B,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,SAAS,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACtF,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,SAAS,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IACrG,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,SAAS,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,SAAS,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,CAAC,OAAO;QACN,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,CAAC,IAAI;QACH,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,CAAC;IACjD,CAAC;IAED,CAAC,MAAM;QACL,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,KAAK,CAAC;IACrD,CAAC;IAED,OAAO,CAAC,QAAqF;QAC3F,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ;YAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACzE,CAAC;IAED,CAAC,MAAM,CAAC,QAAQ,CAAC;QACf,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QACtB,OAAO,UAAU,CAAC;IACpB,CAAC;CACF;AAED,oEAAoE;AACpE,MAAM,UAAU,iBAAiB,CAAC,MAAqC;IACrE,OAAO,+BAA+B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;AACxH,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB,EAAE,IAAY,EAAE,KAA6B;IAClF,MAAM,MAAM,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/G,MAAM,IAAI,GAAG,CAAC,KAAK,QAAQ,EAAE,EAAE,yCAAyC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACnK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,IAAI,IAAI,0BAA0B,EAAE,CAAC,CAAC;IACtG,OAAO,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAoB,EAAE,MAAqC,EAAE,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC;IAC/H,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5D,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;;YACnE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,QAAQ,QAAQ,CAAC,EAAE,CAAC,CAAC;IACzD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,iCAAiC,QAAQ,EAAE,EAAE,CAAC;AAC7E,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAoB,EACpB,MAAqC,EACrC,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC;IAEpC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvE,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;AACzD,CAAC;AAED,iHAAiH;AACjH,MAAM,UAAU,SAAS,CAAC,IAAgB;IACxC,IAAI,IAAI,YAAY,QAAQ,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC;IAC9D,OAAO,QAAQ,IAAI,CAAC,IAAI,IAAI,0BAA0B,WAAW,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;AAChG,CAAC"}
package/dist/bridge.d.ts CHANGED
@@ -17,9 +17,27 @@ export interface NativeBridge {
17
17
  now(): number;
18
18
  setTimer(id: number, delayMs: number, repeats: boolean): void;
19
19
  clearTimer(id: number): void;
20
- /** Starts a request; the answer arrives at `__sbFetchResult(id, result)`. */
21
- /** A body may be a typed array after the request, which names it `{ $bytes: 0 }`, where the host has `hostRequestBytes`. */
20
+ /**
21
+ * Starts a request; the answer arrives at `__sbFetchResult(id, result)`.
22
+ * A body may be a typed array after the request, which names it
23
+ * `{ $bytes: 0 }`, where the host has `hostRequestBytes`; or, where the
24
+ * host `fetchStreams()`, a list of `bodyParts`, each a typed array beside
25
+ * the request or a range of a file on disk, which the host streams in
26
+ * order without reading the files into memory.
27
+ */
22
28
  fetch(id: number, request: string | NativeFetchRequest, ...views: ArrayBufferView[]): void;
29
+ /**
30
+ * Whether `fetch` takes `bodyParts` (a body streamed from files on disk,
31
+ * `InputStream` on the Swift side). Hosts before 0.20 lack it, and then
32
+ * a body holding a picked file is read into memory first.
33
+ */
34
+ fetchStreams?(): boolean;
35
+ /**
36
+ * Cancels request `id` (an `AbortController`'s abort): the `URLSession`
37
+ * task stops, its bytes stop coming, and no `__sbFetchResult` follows.
38
+ * Hosts before 0.20 lack it, and then only the promise is rejected.
39
+ */
40
+ fetchCancel?(id: number): void;
23
41
  /**
24
42
  * Starts loading the image at `url` for its pixel size (image.ts: the
25
43
  * runtime's `Image`), keeping the bytes for the `image` element that
@@ -220,6 +238,19 @@ export interface NativeFetchRequest {
220
238
  body: string | {
221
239
  $bytes: number;
222
240
  } | null;
241
+ /**
242
+ * With `fetchStreams`: the body as parts in order, each a view beside the
243
+ * request or `[start, end)` of a file on disk (one the app may read: in
244
+ * its directories, or picked or dropped), sent as one stream of their
245
+ * total length; `body` is null then.
246
+ */
247
+ bodyParts?: ({
248
+ $bytes: number;
249
+ } | {
250
+ url: string;
251
+ start: number;
252
+ end: number;
253
+ })[];
223
254
  /** The response's body as a `Uint8Array` after the answer's JSON, not base64. */
224
255
  bytes?: boolean;
225
256
  }