@ccheever/exact-ibex-runtime 0.1.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.
- package/package.json +63 -0
- package/src/abort/AbortController.ts +23 -0
- package/src/abort/AbortSignal.ts +152 -0
- package/src/abort/index.ts +2 -0
- package/src/accessibility.ts +12 -0
- package/src/arraybuffer-detach.ts +109 -0
- package/src/base64/base64.ts +168 -0
- package/src/base64/index.ts +1 -0
- package/src/blob/Blob.ts +259 -0
- package/src/blob/File.ts +59 -0
- package/src/blob/FormData.ts +323 -0
- package/src/blob/index.ts +3 -0
- package/src/bootstrap.ts +1946 -0
- package/src/broadcast/BroadcastChannel.ts +280 -0
- package/src/broadcast/index.ts +5 -0
- package/src/cache/Cache.ts +349 -0
- package/src/cache/CacheStorage.ts +89 -0
- package/src/cache/index.ts +27 -0
- package/src/camera/index.ts +6202 -0
- package/src/camera/processor.worker.ts +194 -0
- package/src/camera/scene.ts +195 -0
- package/src/clipboard/Clipboard.ts +129 -0
- package/src/clipboard/ClipboardItem.ts +97 -0
- package/src/clipboard/index.ts +6 -0
- package/src/clone/index.ts +1 -0
- package/src/clone/structuredClone.ts +389 -0
- package/src/clone/transferableSymbols.ts +2 -0
- package/src/compression/CompressionStream.ts +146 -0
- package/src/compression/DecompressionStream.ts +342 -0
- package/src/compression/index.ts +4 -0
- package/src/console/Console.ts +341 -0
- package/src/console/index.ts +2 -0
- package/src/core/accessibility-state.ts +263 -0
- package/src/core/accessibility.ts +184 -0
- package/src/core/agent-state.ts +37 -0
- package/src/core/diagnostics-logs.ts +144 -0
- package/src/core/host-call-bridge.ts +16 -0
- package/src/core/i18n-helpers.ts +189 -0
- package/src/core/locale-state.ts +253 -0
- package/src/core/locale.ts +95 -0
- package/src/crypto/Crypto.ts +2743 -0
- package/src/crypto/index.ts +1 -0
- package/src/diagnostics/logs.ts +7 -0
- package/src/encoding/TextDecoder.ts +1181 -0
- package/src/encoding/TextDecoderStream.ts +58 -0
- package/src/encoding/TextEncoder.ts +180 -0
- package/src/encoding/TextEncoderStream.ts +39 -0
- package/src/encoding/index.ts +8 -0
- package/src/events/CloseEvent.ts +91 -0
- package/src/events/DOMException.ts +409 -0
- package/src/events/ErrorEvent.ts +39 -0
- package/src/events/Event.ts +151 -0
- package/src/events/EventTarget.ts +280 -0
- package/src/events/FocusEvent.ts +27 -0
- package/src/events/KeyboardEvent.ts +46 -0
- package/src/events/MessageEvent.ts +61 -0
- package/src/events/ProgressEvent.ts +33 -0
- package/src/events/PromiseRejectionEvent.ts +31 -0
- package/src/events/index.ts +52 -0
- package/src/eventsource/EventSource.ts +371 -0
- package/src/eventsource/index.ts +2 -0
- package/src/fetch/Headers.ts +642 -0
- package/src/fetch/Request.ts +760 -0
- package/src/fetch/Response.ts +543 -0
- package/src/fetch/body.ts +1256 -0
- package/src/fetch/cookie-jar.ts +566 -0
- package/src/fetch/demo.ts +207 -0
- package/src/fetch/errors.ts +101 -0
- package/src/fetch/fetch.ts +2610 -0
- package/src/fetch/index.ts +101 -0
- package/src/fetch/native-bridge.ts +65 -0
- package/src/fetch/types.ts +258 -0
- package/src/filereader/FileReader.ts +236 -0
- package/src/filereader/index.ts +1 -0
- package/src/fs/Dirent.ts +39 -0
- package/src/fs/ExactFile.ts +450 -0
- package/src/fs/Stats.ts +80 -0
- package/src/fs/index.ts +944 -0
- package/src/fs/promises.ts +386 -0
- package/src/fs/shared.ts +328 -0
- package/src/http-server/index.js +697 -0
- package/src/http-server/index.ts +27 -0
- package/src/identity.generated.ts +14 -0
- package/src/index.ts +283 -0
- package/src/indexeddb/IDBCursor.ts +188 -0
- package/src/indexeddb/IDBDatabase.ts +343 -0
- package/src/indexeddb/IDBFactory.ts +269 -0
- package/src/indexeddb/IDBIndex.ts +194 -0
- package/src/indexeddb/IDBKeyRange.ts +109 -0
- package/src/indexeddb/IDBObjectStore.ts +468 -0
- package/src/indexeddb/IDBRequest.ts +163 -0
- package/src/indexeddb/IDBTransaction.ts +207 -0
- package/src/indexeddb/index.ts +34 -0
- package/src/indexeddb/utils.ts +52 -0
- package/src/inspect/index.ts +1 -0
- package/src/inspect/inspect.ts +465 -0
- package/src/internal/detect.ts +104 -0
- package/src/locale.ts +10 -0
- package/src/location/index.ts +1059 -0
- package/src/locks/LockManager.ts +460 -0
- package/src/locks/index.ts +12 -0
- package/src/media/VideoFrame.ts +58 -0
- package/src/messaging/MessageChannel.ts +31 -0
- package/src/messaging/MessagePort.ts +180 -0
- package/src/messaging/index.ts +2 -0
- package/src/messaging.ts +247 -0
- package/src/native/NativeModules.ts +354 -0
- package/src/native/index.ts +1 -0
- package/src/navigator/Navigator.ts +351 -0
- package/src/navigator/index.ts +1 -0
- package/src/node/Buffer.ts +1786 -0
- package/src/node/index.ts +4 -0
- package/src/node/path.ts +495 -0
- package/src/node/process.ts +2528 -0
- package/src/performance/Performance.ts +532 -0
- package/src/performance/index.ts +21 -0
- package/src/polyfills/array.ts +236 -0
- package/src/polyfills/arraybuffer.ts +172 -0
- package/src/polyfills/groupby.ts +85 -0
- package/src/polyfills/index.ts +85 -0
- package/src/polyfills/intl.ts +1956 -0
- package/src/polyfills/iterator.ts +479 -0
- package/src/polyfills/promise.ts +37 -0
- package/src/polyfills/set.ts +245 -0
- package/src/polyfills/string.ts +85 -0
- package/src/polyfills/typedarray.ts +110 -0
- package/src/promise-rejection-tracking.ts +464 -0
- package/src/react-native/index.ts +388 -0
- package/src/runtime-entry.ts +55 -0
- package/src/scheduling/AnimationFrame.ts +105 -0
- package/src/scheduling/IdleCallback.ts +167 -0
- package/src/scheduling/index.ts +13 -0
- package/src/security/Capabilities.ts +1146 -0
- package/src/security/Permissions.ts +392 -0
- package/src/security/capability-bits.generated.ts +63 -0
- package/src/security/index.ts +16 -0
- package/src/sqlite/Database.ts +456 -0
- package/src/sqlite/Statement.ts +206 -0
- package/src/sqlite/constants.ts +79 -0
- package/src/sqlite/errors.ts +25 -0
- package/src/sqlite/index.ts +34 -0
- package/src/sqlite/module.js +438 -0
- package/src/storage/Storage.ts +291 -0
- package/src/storage/StorageManager.ts +91 -0
- package/src/storage/index.ts +3 -0
- package/src/stream-compat.ts +47 -0
- package/src/streams/ReadableStream.ts +4131 -0
- package/src/streams/TransformStream.ts +375 -0
- package/src/streams/WritableStream.ts +866 -0
- package/src/streams/index.ts +41 -0
- package/src/timers/Timers.ts +296 -0
- package/src/timers/index.ts +11 -0
- package/src/url/URL.ts +656 -0
- package/src/url/URLPattern.ts +850 -0
- package/src/url/URLSearchParams.ts +244 -0
- package/src/url/index.ts +9 -0
- package/src/websocket/WebSocket.ts +770 -0
- package/src/websocket/WebSocketError.ts +52 -0
- package/src/websocket/WebSocketStream.ts +628 -0
- package/src/websocket/index.ts +7 -0
- package/src/window/index.ts +872 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch API
|
|
3
|
+
*
|
|
4
|
+
* Web-standard Fetch API implementation for the Ibex runtime.
|
|
5
|
+
* Follows the WHATWG Fetch Standard with native platform integration.
|
|
6
|
+
*
|
|
7
|
+
* @see https://fetch.spec.whatwg.org/
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { fetch, Headers, Request, Response } from '@exact/runtime/fetch';
|
|
12
|
+
*
|
|
13
|
+
* // Simple GET request
|
|
14
|
+
* const response = await fetch('https://api.example.com/data');
|
|
15
|
+
* const data = await response.json();
|
|
16
|
+
*
|
|
17
|
+
* // POST with JSON body
|
|
18
|
+
* const response = await fetch('https://api.example.com/users', {
|
|
19
|
+
* method: 'POST',
|
|
20
|
+
* headers: { 'Content-Type': 'application/json' },
|
|
21
|
+
* body: JSON.stringify({ name: 'John' }),
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // With AbortController
|
|
25
|
+
* const controller = new AbortController();
|
|
26
|
+
* setTimeout(() => controller.abort(), 5000);
|
|
27
|
+
* const response = await fetch('https://api.example.com/slow', {
|
|
28
|
+
* signal: controller.signal,
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
// Core fetch function
|
|
34
|
+
export { fetch, fetchPolyfill, setNativeFetchModule, isNativeFetchModuleInitialized, installFetchGlobals } from './fetch.js';
|
|
35
|
+
|
|
36
|
+
// Native bridge
|
|
37
|
+
export {
|
|
38
|
+
isNativeFetchAvailable,
|
|
39
|
+
createNativeFetchModule,
|
|
40
|
+
initializeNativeFetch,
|
|
41
|
+
} from './native-bridge.js';
|
|
42
|
+
|
|
43
|
+
// Classes
|
|
44
|
+
export { Headers } from './Headers.js';
|
|
45
|
+
export { Request, type RequestInput } from './Request.js';
|
|
46
|
+
export { Response } from './Response.js';
|
|
47
|
+
|
|
48
|
+
// Cookie jar
|
|
49
|
+
export { cookieJar, CookieJar, setRuntimeOrigin, getRuntimeOrigin } from './cookie-jar.js';
|
|
50
|
+
export type { StoredCookie } from './cookie-jar.js';
|
|
51
|
+
|
|
52
|
+
// Errors
|
|
53
|
+
export { FetchError, AbortError, NetworkError, URLError, BodyConsumedError } from './errors.js';
|
|
54
|
+
|
|
55
|
+
// Types
|
|
56
|
+
export type {
|
|
57
|
+
// Request types
|
|
58
|
+
RequestInit,
|
|
59
|
+
RequestMethod,
|
|
60
|
+
RequestMode,
|
|
61
|
+
RequestCredentials,
|
|
62
|
+
RequestCache,
|
|
63
|
+
RequestRedirect,
|
|
64
|
+
ReferrerPolicy,
|
|
65
|
+
RequestDuplex,
|
|
66
|
+
|
|
67
|
+
// Response types
|
|
68
|
+
ResponseInit,
|
|
69
|
+
ResponseType,
|
|
70
|
+
|
|
71
|
+
// Headers types
|
|
72
|
+
HeadersInit,
|
|
73
|
+
|
|
74
|
+
// Body types
|
|
75
|
+
BodyInit,
|
|
76
|
+
BufferSource,
|
|
77
|
+
|
|
78
|
+
// Native bridge types
|
|
79
|
+
NativeRequestInit,
|
|
80
|
+
NativeResponse,
|
|
81
|
+
NativeStreamingResponse,
|
|
82
|
+
NativeFetchModule,
|
|
83
|
+
} from './types.js';
|
|
84
|
+
|
|
85
|
+
// Body utilities (for advanced usage)
|
|
86
|
+
export {
|
|
87
|
+
bodyToUint8Array,
|
|
88
|
+
readableStreamToUint8Array,
|
|
89
|
+
concatUint8Arrays,
|
|
90
|
+
parseJson,
|
|
91
|
+
parseText,
|
|
92
|
+
parseMultipartFormData,
|
|
93
|
+
extractBoundary,
|
|
94
|
+
isBlob,
|
|
95
|
+
isFormData,
|
|
96
|
+
isArrayBuffer,
|
|
97
|
+
isArrayBufferView,
|
|
98
|
+
} from './body.js';
|
|
99
|
+
|
|
100
|
+
// Stream utilities
|
|
101
|
+
export { isReadableStream } from '../streams/index.js';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native Fetch Bridge
|
|
3
|
+
*
|
|
4
|
+
* Bridges the C++ __nativeFetch function to the TypeScript NativeFetchModule interface.
|
|
5
|
+
* This allows the TypeScript fetch implementation to use the native HTTP layer.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { NativeFetchModule, NativeRequestInit, NativeResponse } from './types.js';
|
|
9
|
+
import { setNativeFetchModule } from './fetch.js';
|
|
10
|
+
|
|
11
|
+
// Declare the global __nativeFetch function installed by C++
|
|
12
|
+
declare global {
|
|
13
|
+
/**
|
|
14
|
+
* Native fetch function installed by ExactHermesBridge.cpp
|
|
15
|
+
* @param url - Request URL
|
|
16
|
+
* @param init - Native request init object
|
|
17
|
+
* @param body - Request body as Uint8Array or null
|
|
18
|
+
* @returns Promise resolving to NativeResponse
|
|
19
|
+
*/
|
|
20
|
+
function __nativeFetch(
|
|
21
|
+
url: string,
|
|
22
|
+
init: NativeRequestInit,
|
|
23
|
+
body: Uint8Array | null
|
|
24
|
+
): Promise<NativeResponse>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Check if the native fetch bridge is available
|
|
29
|
+
*/
|
|
30
|
+
export function isNativeFetchAvailable(): boolean {
|
|
31
|
+
return typeof __nativeFetch === 'function';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Create a NativeFetchModule that wraps the C++ __nativeFetch function
|
|
36
|
+
*/
|
|
37
|
+
export function createNativeFetchModule(): NativeFetchModule | null {
|
|
38
|
+
if (!isNativeFetchAvailable()) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
__exactNativeBridge: true,
|
|
44
|
+
fetch: (
|
|
45
|
+
url: string,
|
|
46
|
+
init: NativeRequestInit,
|
|
47
|
+
body: Uint8Array | null
|
|
48
|
+
): Promise<NativeResponse> => {
|
|
49
|
+
return __nativeFetch(url, init, body);
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Auto-initialize the native fetch module if available.
|
|
56
|
+
* Call this during runtime bootstrap.
|
|
57
|
+
*/
|
|
58
|
+
export function initializeNativeFetch(): boolean {
|
|
59
|
+
const module = createNativeFetchModule();
|
|
60
|
+
if (module) {
|
|
61
|
+
setNativeFetchModule(module);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch API Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Based on the WHATWG Fetch Standard with extensions for Ibex runtime.
|
|
5
|
+
* @see https://fetch.spec.whatwg.org/
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Request Types
|
|
10
|
+
// =============================================================================
|
|
11
|
+
|
|
12
|
+
export type RequestMethod =
|
|
13
|
+
| 'GET'
|
|
14
|
+
| 'POST'
|
|
15
|
+
| 'PUT'
|
|
16
|
+
| 'DELETE'
|
|
17
|
+
| 'PATCH'
|
|
18
|
+
| 'HEAD'
|
|
19
|
+
| 'OPTIONS'
|
|
20
|
+
| 'CONNECT'
|
|
21
|
+
| 'TRACE';
|
|
22
|
+
|
|
23
|
+
export type RequestMode = 'cors' | 'no-cors' | 'same-origin' | 'navigate';
|
|
24
|
+
|
|
25
|
+
export type RequestCredentials = 'omit' | 'same-origin' | 'include';
|
|
26
|
+
|
|
27
|
+
export type RequestCache =
|
|
28
|
+
| 'default'
|
|
29
|
+
| 'no-store'
|
|
30
|
+
| 'reload'
|
|
31
|
+
| 'no-cache'
|
|
32
|
+
| 'force-cache'
|
|
33
|
+
| 'only-if-cached';
|
|
34
|
+
|
|
35
|
+
export type RequestRedirect = 'follow' | 'error' | 'manual';
|
|
36
|
+
|
|
37
|
+
export type ReferrerPolicy =
|
|
38
|
+
| ''
|
|
39
|
+
| 'no-referrer'
|
|
40
|
+
| 'no-referrer-when-downgrade'
|
|
41
|
+
| 'same-origin'
|
|
42
|
+
| 'origin'
|
|
43
|
+
| 'strict-origin'
|
|
44
|
+
| 'origin-when-cross-origin'
|
|
45
|
+
| 'strict-origin-when-cross-origin'
|
|
46
|
+
| 'unsafe-url';
|
|
47
|
+
|
|
48
|
+
export type RequestDuplex = 'half';
|
|
49
|
+
export type TlsCertificateSource = string | ArrayBufferView | Array<string | ArrayBufferView>;
|
|
50
|
+
|
|
51
|
+
export interface FetchTlsOptions {
|
|
52
|
+
ca?: TlsCertificateSource;
|
|
53
|
+
cert?: TlsCertificateSource;
|
|
54
|
+
key?: TlsCertificateSource;
|
|
55
|
+
pfx?: TlsCertificateSource;
|
|
56
|
+
passphrase?: string;
|
|
57
|
+
servername?: string;
|
|
58
|
+
rejectUnauthorized?: boolean;
|
|
59
|
+
checkServerIdentity?: (hostname: string, cert: unknown) => Error | null | undefined;
|
|
60
|
+
[key: string]: unknown;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Request initialization options.
|
|
65
|
+
*/
|
|
66
|
+
export interface RequestInit {
|
|
67
|
+
/** HTTP method (GET, POST, etc.) */
|
|
68
|
+
method?: string;
|
|
69
|
+
/** Request headers */
|
|
70
|
+
headers?: HeadersInit;
|
|
71
|
+
/** Request body */
|
|
72
|
+
body?: BodyInit | null;
|
|
73
|
+
/** Request mode for CORS */
|
|
74
|
+
mode?: RequestMode;
|
|
75
|
+
/** Credentials mode */
|
|
76
|
+
credentials?: RequestCredentials;
|
|
77
|
+
/** Cache mode */
|
|
78
|
+
cache?: RequestCache;
|
|
79
|
+
/** Redirect handling mode */
|
|
80
|
+
redirect?: RequestRedirect;
|
|
81
|
+
/** Referrer URL */
|
|
82
|
+
referrer?: string;
|
|
83
|
+
/** Referrer policy */
|
|
84
|
+
referrerPolicy?: ReferrerPolicy;
|
|
85
|
+
/** Subresource integrity hash */
|
|
86
|
+
integrity?: string;
|
|
87
|
+
/** Abort signal for cancellation */
|
|
88
|
+
signal?: AbortSignal | null;
|
|
89
|
+
/** Abort the request after this many milliseconds. Set to 0 to disable the default timeout. */
|
|
90
|
+
timeout?: number;
|
|
91
|
+
/** Required for streaming uploads */
|
|
92
|
+
duplex?: RequestDuplex;
|
|
93
|
+
/** Keep connection alive after page unloads (not supported) */
|
|
94
|
+
keepalive?: boolean;
|
|
95
|
+
/** Disable automatic content decoding and suppress Accept-Encoding injection */
|
|
96
|
+
decompress?: boolean;
|
|
97
|
+
/** Connect over a Unix domain socket instead of TCP. Bun compatibility extension. */
|
|
98
|
+
unix?: string;
|
|
99
|
+
/** Configure TLS certificate validation for HTTPS requests. Bun compatibility extension. */
|
|
100
|
+
tls?: FetchTlsOptions;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// =============================================================================
|
|
104
|
+
// Response Types
|
|
105
|
+
// =============================================================================
|
|
106
|
+
|
|
107
|
+
export type ResponseType =
|
|
108
|
+
| 'basic'
|
|
109
|
+
| 'cors'
|
|
110
|
+
| 'default'
|
|
111
|
+
| 'error'
|
|
112
|
+
| 'opaque'
|
|
113
|
+
| 'opaqueredirect';
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Response initialization options.
|
|
117
|
+
*/
|
|
118
|
+
export interface ResponseInit {
|
|
119
|
+
/** HTTP status code */
|
|
120
|
+
status?: number;
|
|
121
|
+
/** HTTP status text */
|
|
122
|
+
statusText?: string;
|
|
123
|
+
/** Response headers */
|
|
124
|
+
headers?: HeadersInit;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// =============================================================================
|
|
128
|
+
// Headers Types
|
|
129
|
+
// =============================================================================
|
|
130
|
+
|
|
131
|
+
export type HeadersInit =
|
|
132
|
+
| Headers
|
|
133
|
+
| Record<string, string>
|
|
134
|
+
| Iterable<[string, string]>
|
|
135
|
+
| [string, string][];
|
|
136
|
+
|
|
137
|
+
// =============================================================================
|
|
138
|
+
// Body Types
|
|
139
|
+
// =============================================================================
|
|
140
|
+
|
|
141
|
+
export type BodyInit =
|
|
142
|
+
| Blob
|
|
143
|
+
| BufferSource
|
|
144
|
+
| FormData
|
|
145
|
+
| URLSearchParams
|
|
146
|
+
| ReadableStream<Uint8Array>
|
|
147
|
+
| string;
|
|
148
|
+
|
|
149
|
+
export type BufferSource = ArrayBuffer | ArrayBufferView;
|
|
150
|
+
|
|
151
|
+
// =============================================================================
|
|
152
|
+
// Native Bridge Types
|
|
153
|
+
// =============================================================================
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Native request initialization passed to the native layer.
|
|
157
|
+
*/
|
|
158
|
+
export interface NativeRequestInit {
|
|
159
|
+
method: string;
|
|
160
|
+
headers: [string, string][];
|
|
161
|
+
credentials: RequestCredentials;
|
|
162
|
+
redirect: RequestRedirect;
|
|
163
|
+
decompress?: boolean;
|
|
164
|
+
signal?: AbortSignal | null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Native response data returned from the native layer.
|
|
169
|
+
*/
|
|
170
|
+
export interface NativeResponse {
|
|
171
|
+
status: number;
|
|
172
|
+
statusText: string;
|
|
173
|
+
headers: [string, string][];
|
|
174
|
+
url: string;
|
|
175
|
+
redirected: boolean;
|
|
176
|
+
body: ArrayBuffer | null;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Native streaming response data.
|
|
181
|
+
*/
|
|
182
|
+
export interface NativeStreamingResponse {
|
|
183
|
+
status: number;
|
|
184
|
+
statusText: string;
|
|
185
|
+
headers: [string, string][];
|
|
186
|
+
url: string;
|
|
187
|
+
redirected: boolean;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Interface for the native fetch module.
|
|
192
|
+
* This will be implemented by the native layer (Swift/Kotlin/Rust).
|
|
193
|
+
*/
|
|
194
|
+
export interface NativeFetchModule {
|
|
195
|
+
/** Internal marker for the real native bridge implementation. */
|
|
196
|
+
__exactNativeBridge?: boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Perform a fetch request.
|
|
199
|
+
* @param url The request URL
|
|
200
|
+
* @param init Request options
|
|
201
|
+
* @param body Request body as Uint8Array (if any)
|
|
202
|
+
* @returns Promise resolving to native response
|
|
203
|
+
*/
|
|
204
|
+
fetch(
|
|
205
|
+
url: string,
|
|
206
|
+
init: NativeRequestInit,
|
|
207
|
+
body: Uint8Array | null
|
|
208
|
+
): Promise<NativeResponse>;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Perform a streaming fetch request.
|
|
212
|
+
* @param url The request URL
|
|
213
|
+
* @param init Request options
|
|
214
|
+
* @param body Request body as Uint8Array (if any)
|
|
215
|
+
* @param onHeaders Callback when headers are received
|
|
216
|
+
* @param onData Callback when data chunk is received
|
|
217
|
+
* @param onComplete Callback when response is complete
|
|
218
|
+
* @param onError Callback when error occurs
|
|
219
|
+
* @returns Function to cancel the request
|
|
220
|
+
*/
|
|
221
|
+
fetchStreaming?(
|
|
222
|
+
url: string,
|
|
223
|
+
init: NativeRequestInit,
|
|
224
|
+
body: Uint8Array | null,
|
|
225
|
+
onHeaders: (response: NativeStreamingResponse) => void,
|
|
226
|
+
onData: (chunk: Uint8Array) => void,
|
|
227
|
+
onComplete: () => void,
|
|
228
|
+
onError: (error: Error) => void
|
|
229
|
+
): () => void;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Perform a fetch request with a streaming upload body.
|
|
233
|
+
* The native layer calls onBodyChunk repeatedly to pull body chunks,
|
|
234
|
+
* receiving null when the body is fully sent.
|
|
235
|
+
*
|
|
236
|
+
* Per spec (half-duplex): the request body is fully sent before
|
|
237
|
+
* the response starts streaming.
|
|
238
|
+
*
|
|
239
|
+
* @param url The request URL
|
|
240
|
+
* @param init Request options
|
|
241
|
+
* @param onBodyChunk Async callback that returns the next body chunk,
|
|
242
|
+
* or null when the body is complete
|
|
243
|
+
* @param onHeaders Callback when response headers are received
|
|
244
|
+
* @param onData Callback when response data chunk is received
|
|
245
|
+
* @param onComplete Callback when response is complete
|
|
246
|
+
* @param onError Callback when error occurs
|
|
247
|
+
* @returns Function to cancel the request
|
|
248
|
+
*/
|
|
249
|
+
fetchStreamingUpload?(
|
|
250
|
+
url: string,
|
|
251
|
+
init: NativeRequestInit,
|
|
252
|
+
onBodyChunk: () => Promise<Uint8Array | null>,
|
|
253
|
+
onHeaders: (response: NativeStreamingResponse) => void,
|
|
254
|
+
onData: (chunk: Uint8Array) => void,
|
|
255
|
+
onComplete: () => void,
|
|
256
|
+
onError: (error: Error) => void
|
|
257
|
+
): () => void;
|
|
258
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* FileReader implementation for Ibex runtime (Legacy API)
|
|
4
|
+
*
|
|
5
|
+
* @see https://w3c.github.io/FileAPI/#dfn-filereader
|
|
6
|
+
*
|
|
7
|
+
* Note: Modern code should use Blob.arrayBuffer(), Blob.text(), etc.
|
|
8
|
+
* This is provided for compatibility with legacy libraries.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { EventTarget } from '../events/EventTarget';
|
|
12
|
+
import { Event } from '../events/Event';
|
|
13
|
+
import { ProgressEvent } from '../events/ProgressEvent';
|
|
14
|
+
import { DOMException, createInvalidStateError, createNotSupportedError } from '../events/DOMException';
|
|
15
|
+
import { Blob } from '../blob/Blob';
|
|
16
|
+
|
|
17
|
+
// FileReader states
|
|
18
|
+
const EMPTY = 0;
|
|
19
|
+
const LOADING = 1;
|
|
20
|
+
const DONE = 2;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* FileReader enables asynchronous reading of file or blob contents.
|
|
24
|
+
*/
|
|
25
|
+
export class FileReader extends EventTarget {
|
|
26
|
+
static readonly EMPTY = EMPTY;
|
|
27
|
+
static readonly LOADING = LOADING;
|
|
28
|
+
static readonly DONE = DONE;
|
|
29
|
+
|
|
30
|
+
readonly EMPTY = EMPTY;
|
|
31
|
+
readonly LOADING = LOADING;
|
|
32
|
+
readonly DONE = DONE;
|
|
33
|
+
|
|
34
|
+
#readyState: number = EMPTY;
|
|
35
|
+
#result: string | ArrayBuffer | null = null;
|
|
36
|
+
#error: DOMException | null = null;
|
|
37
|
+
#aborted = false;
|
|
38
|
+
|
|
39
|
+
// Event handlers
|
|
40
|
+
onloadstart: ((this: FileReader, ev: ProgressEvent) => any) | null = null;
|
|
41
|
+
onprogress: ((this: FileReader, ev: ProgressEvent) => any) | null = null;
|
|
42
|
+
onload: ((this: FileReader, ev: ProgressEvent) => any) | null = null;
|
|
43
|
+
onabort: ((this: FileReader, ev: ProgressEvent) => any) | null = null;
|
|
44
|
+
onerror: ((this: FileReader, ev: ProgressEvent) => any) | null = null;
|
|
45
|
+
onloadend: ((this: FileReader, ev: ProgressEvent) => any) | null = null;
|
|
46
|
+
|
|
47
|
+
get readyState(): number {
|
|
48
|
+
return this.#readyState;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get result(): string | ArrayBuffer | null {
|
|
52
|
+
return this.#result;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get error(): DOMException | null {
|
|
56
|
+
return this.#error;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Check if reader is ready to start a new read operation.
|
|
61
|
+
* Throws InvalidStateError if already loading.
|
|
62
|
+
*/
|
|
63
|
+
#checkReadyState(): void {
|
|
64
|
+
if (this.#readyState === LOADING) {
|
|
65
|
+
throw createInvalidStateError('FileReader is already loading');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Read blob as ArrayBuffer.
|
|
71
|
+
*/
|
|
72
|
+
readAsArrayBuffer(blob: Blob): void {
|
|
73
|
+
this.#checkReadyState();
|
|
74
|
+
this.#read(blob, 'arraybuffer');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Read blob as binary string.
|
|
79
|
+
* @deprecated Use readAsArrayBuffer instead.
|
|
80
|
+
*/
|
|
81
|
+
readAsBinaryString(blob: Blob): void {
|
|
82
|
+
this.#checkReadyState();
|
|
83
|
+
this.#read(blob, 'binarystring');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Read blob as text.
|
|
88
|
+
*/
|
|
89
|
+
readAsText(blob: Blob, encoding?: string): void {
|
|
90
|
+
this.#checkReadyState();
|
|
91
|
+
this.#read(blob, 'text', encoding);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Read blob as data URL.
|
|
96
|
+
*/
|
|
97
|
+
readAsDataURL(blob: Blob): void {
|
|
98
|
+
this.#checkReadyState();
|
|
99
|
+
this.#read(blob, 'dataurl');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Abort the read operation.
|
|
104
|
+
*/
|
|
105
|
+
abort(): void {
|
|
106
|
+
if (this.#readyState === EMPTY || this.#readyState === DONE) {
|
|
107
|
+
this.#result = null;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (this.#readyState === LOADING) {
|
|
112
|
+
this.#readyState = DONE;
|
|
113
|
+
this.#result = null;
|
|
114
|
+
this.#aborted = true;
|
|
115
|
+
|
|
116
|
+
this.#fireEvent('abort');
|
|
117
|
+
this.#fireEvent('loadend');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Internal read implementation.
|
|
123
|
+
*/
|
|
124
|
+
async #read(blob: Blob, format: 'arraybuffer' | 'binarystring' | 'text' | 'dataurl', encoding?: string): Promise<void> {
|
|
125
|
+
// State check is done in #checkReadyState() before calling this method
|
|
126
|
+
this.#readyState = LOADING;
|
|
127
|
+
this.#result = null;
|
|
128
|
+
this.#error = null;
|
|
129
|
+
this.#aborted = false;
|
|
130
|
+
|
|
131
|
+
this.#fireProgressEvent('loadstart', 0, blob.size);
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
// Read the blob data
|
|
135
|
+
const buffer = await blob.arrayBuffer();
|
|
136
|
+
|
|
137
|
+
if (this.#aborted) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Fire progress event
|
|
142
|
+
this.#fireProgressEvent('progress', buffer.byteLength, blob.size);
|
|
143
|
+
|
|
144
|
+
// Convert to requested format
|
|
145
|
+
switch (format) {
|
|
146
|
+
case 'arraybuffer':
|
|
147
|
+
this.#result = buffer;
|
|
148
|
+
break;
|
|
149
|
+
|
|
150
|
+
case 'binarystring': {
|
|
151
|
+
const bytes = new Uint8Array(buffer);
|
|
152
|
+
let result = '';
|
|
153
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
154
|
+
result += String.fromCharCode(bytes[i]);
|
|
155
|
+
}
|
|
156
|
+
this.#result = result;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
case 'text': {
|
|
161
|
+
const decoder = new TextDecoder(encoding || 'utf-8');
|
|
162
|
+
this.#result = decoder.decode(buffer);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
case 'dataurl': {
|
|
167
|
+
const bytes = new Uint8Array(buffer);
|
|
168
|
+
let binary = '';
|
|
169
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
170
|
+
binary += String.fromCharCode(bytes[i]);
|
|
171
|
+
}
|
|
172
|
+
const base64 = btoa(binary);
|
|
173
|
+
const mimeType = blob.type || 'application/octet-stream';
|
|
174
|
+
this.#result = `data:${mimeType};base64,${base64}`;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
this.#readyState = DONE;
|
|
180
|
+
this.#fireProgressEvent('load', buffer.byteLength, blob.size);
|
|
181
|
+
this.#fireProgressEvent('loadend', buffer.byteLength, blob.size);
|
|
182
|
+
|
|
183
|
+
} catch (err) {
|
|
184
|
+
if (this.#aborted) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
this.#readyState = DONE;
|
|
189
|
+
this.#error = new DOMException(
|
|
190
|
+
err instanceof Error ? err.message : 'Read failed',
|
|
191
|
+
'NotReadableError'
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
this.#fireProgressEvent('error', 0, blob.size);
|
|
195
|
+
this.#fireProgressEvent('loadend', 0, blob.size);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Fire a simple event.
|
|
201
|
+
*/
|
|
202
|
+
#fireEvent(type: string): void {
|
|
203
|
+
const event = new Event(type);
|
|
204
|
+
|
|
205
|
+
const handler = (this as any)[`on${type}`];
|
|
206
|
+
if (handler) {
|
|
207
|
+
handler.call(this, event);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
this.dispatchEvent(event);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Fire a progress event.
|
|
215
|
+
*/
|
|
216
|
+
#fireProgressEvent(type: string, loaded: number, total: number): void {
|
|
217
|
+
const event = new ProgressEvent(type, {
|
|
218
|
+
lengthComputable: total > 0,
|
|
219
|
+
loaded,
|
|
220
|
+
total,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const handler = (this as any)[`on${type}`];
|
|
224
|
+
if (handler) {
|
|
225
|
+
handler.call(this, event);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
this.dispatchEvent(event);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
get [Symbol.toStringTag](): string {
|
|
232
|
+
return 'FileReader';
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export default FileReader;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FileReader } from './FileReader';
|
package/src/fs/Dirent.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Stats } from './Stats';
|
|
2
|
+
|
|
3
|
+
export class Dirent {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
private readonly stats: Stats;
|
|
6
|
+
|
|
7
|
+
constructor(name: string, stats: Stats) {
|
|
8
|
+
this.name = name;
|
|
9
|
+
this.stats = stats;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
isFile(): boolean {
|
|
13
|
+
return this.stats.isFile();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
isDirectory(): boolean {
|
|
17
|
+
return this.stats.isDirectory();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
isBlockDevice(): boolean {
|
|
21
|
+
return this.stats.isBlockDevice();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
isCharacterDevice(): boolean {
|
|
25
|
+
return this.stats.isCharacterDevice();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
isSymbolicLink(): boolean {
|
|
29
|
+
return this.stats.isSymbolicLink();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
isFIFO(): boolean {
|
|
33
|
+
return this.stats.isFIFO();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
isSocket(): boolean {
|
|
37
|
+
return this.stats.isSocket();
|
|
38
|
+
}
|
|
39
|
+
}
|