@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,465 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object inspection utility (similar to Node's util.inspect, Bun.inspect, Deno.inspect)
|
|
3
|
+
*
|
|
4
|
+
* Pretty-prints objects with colors, depth limiting, and smart formatting.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface InspectOptions {
|
|
8
|
+
/** Show colors (ANSI escape codes) */
|
|
9
|
+
colors?: boolean;
|
|
10
|
+
/** Maximum depth to traverse */
|
|
11
|
+
depth?: number;
|
|
12
|
+
/** Show hidden (non-enumerable) properties */
|
|
13
|
+
showHidden?: boolean;
|
|
14
|
+
/** Maximum array/object elements to show */
|
|
15
|
+
maxArrayLength?: number;
|
|
16
|
+
/** Maximum string length */
|
|
17
|
+
maxStringLength?: number;
|
|
18
|
+
/** Compact mode (less whitespace) */
|
|
19
|
+
compact?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const DEFAULT_OPTIONS: Required<InspectOptions> = {
|
|
23
|
+
colors: true,
|
|
24
|
+
depth: 4,
|
|
25
|
+
showHidden: false,
|
|
26
|
+
maxArrayLength: 100,
|
|
27
|
+
maxStringLength: 10000,
|
|
28
|
+
compact: true,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// ANSI color codes
|
|
32
|
+
const colors = {
|
|
33
|
+
reset: '\x1b[0m',
|
|
34
|
+
bold: '\x1b[1m',
|
|
35
|
+
dim: '\x1b[2m',
|
|
36
|
+
|
|
37
|
+
// Types
|
|
38
|
+
number: '\x1b[33m', // yellow
|
|
39
|
+
string: '\x1b[32m', // green
|
|
40
|
+
boolean: '\x1b[33m', // yellow
|
|
41
|
+
null: '\x1b[1m', // bold
|
|
42
|
+
undefined: '\x1b[2m', // dim
|
|
43
|
+
symbol: '\x1b[32m', // green
|
|
44
|
+
function: '\x1b[36m', // cyan
|
|
45
|
+
|
|
46
|
+
// Structures
|
|
47
|
+
key: '\x1b[0m', // reset
|
|
48
|
+
special: '\x1b[36m', // cyan (Date, RegExp, etc.)
|
|
49
|
+
bracket: '\x1b[2m', // dim
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
function colorize(text: string, color: string, useColors: boolean): string {
|
|
53
|
+
return useColors ? color + text + colors.reset : text;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function inspectPrimitive(value: any, opts: Required<InspectOptions>): string {
|
|
57
|
+
if (value === null) {
|
|
58
|
+
return colorize('null', colors.null, opts.colors);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (value === undefined) {
|
|
62
|
+
return colorize('undefined', colors.undefined, opts.colors);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (typeof value === 'number') {
|
|
66
|
+
return colorize(String(value), colors.number, opts.colors);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (typeof value === 'boolean') {
|
|
70
|
+
return colorize(String(value), colors.boolean, opts.colors);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (typeof value === 'string') {
|
|
74
|
+
const truncated = value.length > opts.maxStringLength
|
|
75
|
+
? value.slice(0, opts.maxStringLength) + '...'
|
|
76
|
+
: value;
|
|
77
|
+
const escaped = JSON.stringify(truncated);
|
|
78
|
+
return colorize(escaped, colors.string, opts.colors);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (typeof value === 'symbol') {
|
|
82
|
+
return colorize(String(value), colors.symbol, opts.colors);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (typeof value === 'function') {
|
|
86
|
+
const name = value.name || 'anonymous';
|
|
87
|
+
const params = 'a0, a1, a2'; // Simplified - we don't have access to Function.length easily
|
|
88
|
+
return colorize(`[Function: ${name}]`, colors.function, opts.colors);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return String(value);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function inspectArray(arr: any[], depth: number, opts: Required<InspectOptions>, seen: Set<any>): string {
|
|
95
|
+
if (depth >= opts.depth) {
|
|
96
|
+
return colorize('[Array]', colors.special, opts.colors);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const items: string[] = [];
|
|
100
|
+
const limit = Math.min(arr.length, opts.maxArrayLength);
|
|
101
|
+
|
|
102
|
+
for (let i = 0; i < limit; i++) {
|
|
103
|
+
items.push(inspectValue(arr[i], depth + 1, opts, seen));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (arr.length > opts.maxArrayLength) {
|
|
107
|
+
items.push(colorize(`... ${arr.length - opts.maxArrayLength} more items`, colors.dim, opts.colors));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const open = colorize('[', colors.bracket, opts.colors);
|
|
111
|
+
const close = colorize(']', colors.bracket, opts.colors);
|
|
112
|
+
|
|
113
|
+
if (opts.compact) {
|
|
114
|
+
return open + ' ' + items.join(', ') + ' ' + close;
|
|
115
|
+
} else {
|
|
116
|
+
return open + '\n ' + items.join(',\n ') + '\n' + close;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function indentMultiline(text: string, prefix: string): string {
|
|
121
|
+
return text.replace(/\n/g, `\n${prefix}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function isURLSearchParamsLike(value: any): boolean {
|
|
125
|
+
return !!value &&
|
|
126
|
+
typeof value === 'object' &&
|
|
127
|
+
typeof value.append === 'function' &&
|
|
128
|
+
typeof value.get === 'function' &&
|
|
129
|
+
typeof value.getAll === 'function' &&
|
|
130
|
+
typeof value.entries === 'function' &&
|
|
131
|
+
typeof value.toString === 'function';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function inspectURLSearchParamsLike(value: any): string | null {
|
|
135
|
+
try {
|
|
136
|
+
const groups: Array<{ key: string; values: string[] }> = [];
|
|
137
|
+
|
|
138
|
+
for (const entry of value.entries()) {
|
|
139
|
+
const key = String(entry[0]);
|
|
140
|
+
const entryValue = String(entry[1]);
|
|
141
|
+
const group = groups.find(item => item.key === key);
|
|
142
|
+
|
|
143
|
+
if (group) {
|
|
144
|
+
group.values.push(entryValue);
|
|
145
|
+
} else {
|
|
146
|
+
groups.push({ key, values: [entryValue] });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (groups.length === 0) {
|
|
151
|
+
return 'URLSearchParams {}';
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const lines = groups.map(group => {
|
|
155
|
+
const renderedValue = group.values.length === 1
|
|
156
|
+
? JSON.stringify(group.values[0])
|
|
157
|
+
: `[ ${group.values.map(item => JSON.stringify(item)).join(', ')} ]`;
|
|
158
|
+
return ` ${JSON.stringify(group.key)}: ${renderedValue},`;
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
return `URLSearchParams {\n${lines.join('\n')}\n}`;
|
|
162
|
+
} catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function isURLLike(value: any): boolean {
|
|
168
|
+
return !!value &&
|
|
169
|
+
typeof value === 'object' &&
|
|
170
|
+
typeof value.href === 'string' &&
|
|
171
|
+
typeof value.origin === 'string' &&
|
|
172
|
+
typeof value.protocol === 'string' &&
|
|
173
|
+
typeof value.username === 'string' &&
|
|
174
|
+
typeof value.password === 'string' &&
|
|
175
|
+
typeof value.host === 'string' &&
|
|
176
|
+
typeof value.hostname === 'string' &&
|
|
177
|
+
typeof value.port === 'string' &&
|
|
178
|
+
typeof value.pathname === 'string' &&
|
|
179
|
+
typeof value.hash === 'string' &&
|
|
180
|
+
typeof value.search === 'string' &&
|
|
181
|
+
value.searchParams &&
|
|
182
|
+
typeof value.searchParams === 'object' &&
|
|
183
|
+
typeof value.toJSON === 'function' &&
|
|
184
|
+
typeof value.toString === 'function';
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function inspectURLLike(obj: any, depth: number, opts: Required<InspectOptions>, seen: Set<any>): string {
|
|
188
|
+
const searchParams = indentMultiline(inspectValue(obj.searchParams, depth + 1, opts, seen), ' ');
|
|
189
|
+
|
|
190
|
+
return `URL {
|
|
191
|
+
href: ${JSON.stringify(obj.href)},
|
|
192
|
+
origin: ${JSON.stringify(obj.origin)},
|
|
193
|
+
protocol: ${JSON.stringify(obj.protocol)},
|
|
194
|
+
username: ${JSON.stringify(obj.username)},
|
|
195
|
+
password: ${JSON.stringify(obj.password)},
|
|
196
|
+
host: ${JSON.stringify(obj.host)},
|
|
197
|
+
hostname: ${JSON.stringify(obj.hostname)},
|
|
198
|
+
port: ${JSON.stringify(obj.port)},
|
|
199
|
+
pathname: ${JSON.stringify(obj.pathname)},
|
|
200
|
+
hash: ${JSON.stringify(obj.hash)},
|
|
201
|
+
search: ${JSON.stringify(obj.search)},
|
|
202
|
+
searchParams: ${searchParams},
|
|
203
|
+
toJSON: [Function: toJSON],
|
|
204
|
+
toString: [Function: toString],
|
|
205
|
+
}`;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function inspectObject(obj: any, depth: number, opts: Required<InspectOptions>, seen: Set<any>): string {
|
|
209
|
+
if (depth >= opts.depth) {
|
|
210
|
+
return colorize('[Object]', colors.special, opts.colors);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Special cases - use duck typing instead of instanceof for cross-realm compatibility
|
|
214
|
+
if (isURLSearchParamsLike(obj)) {
|
|
215
|
+
const inspected = inspectURLSearchParamsLike(obj);
|
|
216
|
+
if (inspected !== null) {
|
|
217
|
+
return inspected;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (isURLLike(obj)) {
|
|
222
|
+
return inspectURLLike(obj, depth, opts, seen);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (typeof obj.toISOString === 'function' && typeof obj.getMonth === 'function') {
|
|
226
|
+
// Date object
|
|
227
|
+
try {
|
|
228
|
+
return colorize(obj.toISOString(), colors.special, opts.colors);
|
|
229
|
+
} catch {
|
|
230
|
+
return colorize(String(obj), colors.special, opts.colors);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (typeof obj.test === 'function' && typeof obj.exec === 'function' && obj.source !== undefined) {
|
|
235
|
+
// RegExp object
|
|
236
|
+
return colorize(String(obj), colors.special, opts.colors);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (obj.name && obj.message && obj.stack) {
|
|
240
|
+
// Error object
|
|
241
|
+
return colorize(`${obj.name}: ${obj.message}`, colors.special, opts.colors);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (typeof obj.get === 'function' && typeof obj.set === 'function' && typeof obj.has === 'function' && typeof obj.entries === 'function' && obj.size !== undefined) {
|
|
245
|
+
// Map object
|
|
246
|
+
try {
|
|
247
|
+
const entries: string[] = [];
|
|
248
|
+
let count = 0;
|
|
249
|
+
for (const [key, value] of obj.entries()) {
|
|
250
|
+
if (count++ >= opts.maxArrayLength) break;
|
|
251
|
+
entries.push(
|
|
252
|
+
inspectValue(key, depth + 1, opts, seen) + ' => ' +
|
|
253
|
+
inspectValue(value, depth + 1, opts, seen)
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
if (obj.size > opts.maxArrayLength) {
|
|
257
|
+
entries.push(colorize(`... ${obj.size - opts.maxArrayLength} more entries`, colors.dim, opts.colors));
|
|
258
|
+
}
|
|
259
|
+
return colorize('Map(', colors.special, opts.colors) + obj.size + ') { ' + entries.join(', ') + ' }';
|
|
260
|
+
} catch {
|
|
261
|
+
// Fall through to regular object handling
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (typeof obj.has === 'function' && typeof obj.add === 'function' && typeof obj.values === 'function' && obj.size !== undefined) {
|
|
266
|
+
// Set object
|
|
267
|
+
try {
|
|
268
|
+
const values: string[] = [];
|
|
269
|
+
let count = 0;
|
|
270
|
+
for (const value of obj.values()) {
|
|
271
|
+
if (count++ >= opts.maxArrayLength) break;
|
|
272
|
+
values.push(inspectValue(value, depth + 1, opts, seen));
|
|
273
|
+
}
|
|
274
|
+
if (obj.size > opts.maxArrayLength) {
|
|
275
|
+
values.push(colorize(`... ${obj.size - opts.maxArrayLength} more items`, colors.dim, opts.colors));
|
|
276
|
+
}
|
|
277
|
+
return colorize('Set(', colors.special, opts.colors) + obj.size + ') { ' + values.join(', ') + ' }';
|
|
278
|
+
} catch {
|
|
279
|
+
// Fall through to regular object handling
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Module object (check for CommonJS/ES module markers)
|
|
284
|
+
// CommonJS modules often have __esModule or are returned from require()
|
|
285
|
+
if (obj.__esModule || obj.default !== undefined || obj.exports !== undefined) {
|
|
286
|
+
// Show as Module with exported names
|
|
287
|
+
const keys = Object.keys(obj).filter(k => k !== '__esModule');
|
|
288
|
+
if (keys.length === 0) {
|
|
289
|
+
return colorize('Module { }', colors.special, opts.colors);
|
|
290
|
+
} else if (keys.length <= 5) {
|
|
291
|
+
const exports = keys.map(k => colorize(k, colors.key, opts.colors)).join(', ');
|
|
292
|
+
return colorize('Module { ', colors.special, opts.colors) + exports + colorize(' }', colors.special, opts.colors);
|
|
293
|
+
} else {
|
|
294
|
+
const firstFive = keys.slice(0, 5).map(k => colorize(k, colors.key, opts.colors)).join(', ');
|
|
295
|
+
const remaining = keys.length - 5;
|
|
296
|
+
return colorize('Module { ', colors.special, opts.colors) +
|
|
297
|
+
firstFive +
|
|
298
|
+
colorize(`, ...${remaining} more`, colors.dim, opts.colors) +
|
|
299
|
+
colorize(' }', colors.special, opts.colors);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Promise object (check for .then method)
|
|
304
|
+
if (typeof obj.then === 'function' && typeof obj.catch === 'function') {
|
|
305
|
+
try {
|
|
306
|
+
// Try to inspect Hermes promise internals for state
|
|
307
|
+
// _x: 0 = pending, 1 = fulfilled, 2 = rejected
|
|
308
|
+
// _z: resolved/rejected value
|
|
309
|
+
const state = (obj as any)._x;
|
|
310
|
+
const value = (obj as any)._z;
|
|
311
|
+
|
|
312
|
+
// If there's a value (even if state is still technically pending due to microtask queue)
|
|
313
|
+
// show it as fulfilled. This matches Chrome DevTools behavior.
|
|
314
|
+
if (value !== undefined && value !== null && state !== 2) {
|
|
315
|
+
return colorize('Promise { ', colors.special, opts.colors) +
|
|
316
|
+
colorize('<fulfilled>', colors.dim, opts.colors) + ': ' +
|
|
317
|
+
inspectValue(value, depth + 1, opts, seen) +
|
|
318
|
+
colorize(' }', colors.special, opts.colors);
|
|
319
|
+
} else if (state === 2) {
|
|
320
|
+
return colorize('Promise { ', colors.special, opts.colors) +
|
|
321
|
+
colorize('<rejected>', colors.dim, opts.colors) + ': ' +
|
|
322
|
+
inspectValue(value, depth + 1, opts, seen) +
|
|
323
|
+
colorize(' }', colors.special, opts.colors);
|
|
324
|
+
} else {
|
|
325
|
+
// Truly pending (no value yet)
|
|
326
|
+
return colorize('Promise { ', colors.special, opts.colors) +
|
|
327
|
+
colorize('<pending>', colors.dim, opts.colors) +
|
|
328
|
+
colorize(' }', colors.special, opts.colors);
|
|
329
|
+
}
|
|
330
|
+
} catch {
|
|
331
|
+
// Fall back to generic Promise label
|
|
332
|
+
return colorize('Promise { ... }', colors.special, opts.colors);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Regular object
|
|
337
|
+
const keys = opts.showHidden
|
|
338
|
+
? Object.getOwnPropertyNames(obj)
|
|
339
|
+
: Object.keys(obj);
|
|
340
|
+
|
|
341
|
+
if (keys.length === 0) {
|
|
342
|
+
return '{}';
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const pairs: string[] = [];
|
|
346
|
+
const limit = Math.min(keys.length, opts.maxArrayLength);
|
|
347
|
+
|
|
348
|
+
for (let i = 0; i < limit; i++) {
|
|
349
|
+
const key = keys[i];
|
|
350
|
+
const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key);
|
|
351
|
+
const keyStr = needsQuotes ? JSON.stringify(key) : key;
|
|
352
|
+
const coloredKey = colorize(keyStr, colors.key, opts.colors);
|
|
353
|
+
const value = inspectValue(obj[key], depth + 1, opts, seen);
|
|
354
|
+
pairs.push(coloredKey + ': ' + value);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (keys.length > opts.maxArrayLength) {
|
|
358
|
+
pairs.push(colorize(`... ${keys.length - opts.maxArrayLength} more keys`, colors.dim, opts.colors));
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const open = colorize('{', colors.bracket, opts.colors);
|
|
362
|
+
const close = colorize('}', colors.bracket, opts.colors);
|
|
363
|
+
|
|
364
|
+
if (opts.compact) {
|
|
365
|
+
return open + ' ' + pairs.join(', ') + ' ' + close;
|
|
366
|
+
} else {
|
|
367
|
+
return open + '\n ' + pairs.join(',\n ') + '\n' + close;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function inspectTypedArray(value: { length: number; [index: number]: number; constructor?: { name?: string }; [Symbol.toStringTag]?: string }, depth: number, opts: Required<InspectOptions>): string {
|
|
372
|
+
const isBuffer = value[Symbol.toStringTag] === 'Buffer' || (value.constructor && value.constructor.name === 'Buffer');
|
|
373
|
+
const typeName = isBuffer ? 'Buffer' : (value.constructor?.name || 'TypedArray');
|
|
374
|
+
|
|
375
|
+
if (isBuffer) {
|
|
376
|
+
// Node.js style: <Buffer 23 20 45 78 61 63 74 0a ...>
|
|
377
|
+
const maxBytes = 50;
|
|
378
|
+
const hexParts: string[] = [];
|
|
379
|
+
const limit = Math.min(value.length, maxBytes);
|
|
380
|
+
for (let i = 0; i < limit; i++) {
|
|
381
|
+
hexParts.push(value[i].toString(16).padStart(2, '0'));
|
|
382
|
+
}
|
|
383
|
+
const truncated = value.length > maxBytes
|
|
384
|
+
? ` ... ${value.length - maxBytes} more bytes`
|
|
385
|
+
: '';
|
|
386
|
+
return colorize(`<Buffer ${hexParts.join(' ')}${truncated}>`, colors.special, opts.colors);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Other TypedArrays: Uint8Array(5) [ 1, 2, 3, 4, 5 ]
|
|
390
|
+
const maxItems = Math.min(value.length, opts.maxArrayLength);
|
|
391
|
+
const items: string[] = [];
|
|
392
|
+
for (let i = 0; i < maxItems; i++) {
|
|
393
|
+
items.push(colorize(String(value[i]), colors.number, opts.colors));
|
|
394
|
+
}
|
|
395
|
+
const truncated = value.length > opts.maxArrayLength
|
|
396
|
+
? colorize(` ... ${value.length - opts.maxArrayLength} more items`, colors.dim, opts.colors)
|
|
397
|
+
: '';
|
|
398
|
+
return `${typeName}(${value.length}) [ ${items.join(', ')}${truncated} ]`;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function inspectValue(value: any, depth: number, opts: Required<InspectOptions>, seen: Set<any>): string {
|
|
402
|
+
const type = typeof value;
|
|
403
|
+
|
|
404
|
+
// Primitives and functions
|
|
405
|
+
if (type !== 'object' || value === null) {
|
|
406
|
+
return inspectPrimitive(value, opts);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Circular reference detection
|
|
410
|
+
if (seen.has(value)) {
|
|
411
|
+
return colorize('[Circular]', colors.special, opts.colors);
|
|
412
|
+
}
|
|
413
|
+
seen.add(value);
|
|
414
|
+
|
|
415
|
+
try {
|
|
416
|
+
// Buffer / TypedArray - show hex bytes like Node.js
|
|
417
|
+
if (ArrayBuffer.isView(value) && !(value instanceof DataView)) {
|
|
418
|
+
return inspectTypedArray(value as any, depth, opts);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Arrays
|
|
422
|
+
if (Array.isArray(value)) {
|
|
423
|
+
return inspectArray(value, depth, opts, seen);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// Objects (including special types)
|
|
427
|
+
return inspectObject(value, depth, opts, seen);
|
|
428
|
+
} finally {
|
|
429
|
+
seen.delete(value);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Inspect a value and return a formatted string representation
|
|
435
|
+
* Similar to Node's util.inspect, Bun.inspect, and Deno.inspect
|
|
436
|
+
*/
|
|
437
|
+
export function inspect(value: any, options?: InspectOptions): string {
|
|
438
|
+
const opts: Required<InspectOptions> = {
|
|
439
|
+
...DEFAULT_OPTIONS,
|
|
440
|
+
...options,
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
return inspectValue(value, 0, opts, new Set());
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Install on the Exact global — defensively: hosts may already provide an
|
|
447
|
+
// `inspect` (possibly as a getter-only accessor), and a convenience install
|
|
448
|
+
// must never hard-fail module evaluation (it broke native agent boot as the
|
|
449
|
+
// follow-on failure behind LLP 0176).
|
|
450
|
+
if (typeof globalThis.Exact !== 'undefined') {
|
|
451
|
+
const exactGlobal = (globalThis as { Exact?: Record<string, unknown> }).Exact!;
|
|
452
|
+
const descriptor = Object.getOwnPropertyDescriptor(exactGlobal, 'inspect');
|
|
453
|
+
if (!descriptor || descriptor.configurable || descriptor.writable) {
|
|
454
|
+
try {
|
|
455
|
+
Object.defineProperty(exactGlobal, 'inspect', {
|
|
456
|
+
value: inspect,
|
|
457
|
+
writable: true,
|
|
458
|
+
configurable: true,
|
|
459
|
+
enumerable: true,
|
|
460
|
+
});
|
|
461
|
+
} catch {
|
|
462
|
+
// The host owns Exact.inspect; keep its implementation.
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal detection utilities
|
|
3
|
+
*
|
|
4
|
+
* These are used by modules that need to detect engine/platform
|
|
5
|
+
* WITHOUT importing from bootstrap (to avoid circular dependencies).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Get the runtime version
|
|
10
|
+
*/
|
|
11
|
+
export function getRuntimeVersion(): string {
|
|
12
|
+
return "0.1.0";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Detect the JavaScript engine at runtime.
|
|
17
|
+
*/
|
|
18
|
+
export function detectEngine(): "Hermes" | "JSC" | "V8" | "browser" | "unknown" {
|
|
19
|
+
const g = globalThis as any;
|
|
20
|
+
|
|
21
|
+
// Hermes detection
|
|
22
|
+
if (typeof g.HermesInternal !== "undefined") {
|
|
23
|
+
return "Hermes";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Browser detection (must come before V8 check since Chrome has both)
|
|
27
|
+
if (typeof document !== "undefined" && document.createElement) {
|
|
28
|
+
return "browser";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// V8 detection (Node.js or standalone V8)
|
|
32
|
+
if (typeof g.v8debug !== "undefined" || g._v8runtime) {
|
|
33
|
+
return "V8";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// JSC detection (JavaScriptCore specific globals)
|
|
37
|
+
if (typeof g.gc === "function" && !g.v8debug) {
|
|
38
|
+
return "JSC";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return "unknown";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Detect the platform at runtime.
|
|
46
|
+
* Note: This must NOT access navigator to avoid circular dependency.
|
|
47
|
+
*/
|
|
48
|
+
export function detectPlatform(): string {
|
|
49
|
+
const g = globalThis as any;
|
|
50
|
+
|
|
51
|
+
if (typeof g.__exactPlatform === "string" && g.__exactPlatform.length > 0) {
|
|
52
|
+
return g.__exactPlatform;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Browser/web detection (check for DOM document, not our window shim)
|
|
56
|
+
if (typeof document !== "undefined" && document.createElement) {
|
|
57
|
+
return "web";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// If process exists (CLI/Node-like), prefer it unless it's Exact's process shim.
|
|
61
|
+
const hostProcess = g.process;
|
|
62
|
+
if (hostProcess) {
|
|
63
|
+
let isExactProcess = false;
|
|
64
|
+
try {
|
|
65
|
+
const versions = hostProcess.versions;
|
|
66
|
+
isExactProcess = !!(versions && typeof versions === "object" && (typeof versions.ibex === "string" || typeof versions.exact === "string"));
|
|
67
|
+
} catch {
|
|
68
|
+
isExactProcess = false;
|
|
69
|
+
}
|
|
70
|
+
if (!isExactProcess) {
|
|
71
|
+
try {
|
|
72
|
+
const platform = hostProcess.platform;
|
|
73
|
+
if (typeof platform === "string" && platform.length > 0) {
|
|
74
|
+
return platform;
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
// Ignore host process platform lookup errors and continue fallback chain.
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Check for Hermes-specific platform hints
|
|
83
|
+
if (typeof g.HermesInternal !== "undefined") {
|
|
84
|
+
// Hermes is used in Exact for iOS/Android
|
|
85
|
+
// Default to iOS since that's our primary target
|
|
86
|
+
return "ios";
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return "unknown";
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Runtime info object with lazy getters
|
|
94
|
+
*/
|
|
95
|
+
export const runtimeInfo = {
|
|
96
|
+
name: "Exact",
|
|
97
|
+
version: getRuntimeVersion(),
|
|
98
|
+
get engine() {
|
|
99
|
+
return detectEngine();
|
|
100
|
+
},
|
|
101
|
+
get platform() {
|
|
102
|
+
return detectPlatform();
|
|
103
|
+
},
|
|
104
|
+
};
|
package/src/locale.ts
ADDED