@happyvertical/json 0.74.8

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sonic-BVfKq74R.js","sources":["../../src/adapters/native.ts","../../src/adapters/sonic.ts"],"sourcesContent":["/**\n * Native JavaScript JSON adapter\n *\n * This adapter uses the built-in JSON object as a fallback when\n * the Rust SIMD-accelerated adapter is not available.\n */\n\nimport type {\n AdapterInfo,\n JSONAdapter,\n ParseError,\n Replacer,\n Result,\n Reviver,\n StringifyError,\n} from '../types.js';\n\n/**\n * Native JavaScript JSON adapter implementation\n *\n * Provides the same interface as the Rust adapter but uses\n * the built-in JSON object. Useful as a fallback and for\n * environments where native bindings can't be loaded.\n */\nexport class NativeAdapter implements JSONAdapter {\n readonly name = 'native' as const;\n readonly isNative = true;\n\n /**\n * Parse a JSON string using native JSON.parse\n */\n parse<T = unknown>(text: string, reviver?: Reviver): T {\n return JSON.parse(text, reviver) as T;\n }\n\n /**\n * Stringify a value using native JSON.stringify\n */\n stringify(\n value: unknown,\n replacer?: Replacer,\n space?: number | string,\n ): string {\n // Handle the replacer type properly - separate calls for each overload\n let result: string | undefined;\n\n if (typeof replacer === 'function') {\n result = JSON.stringify(value, replacer, space);\n } else if (Array.isArray(replacer)) {\n result = JSON.stringify(value, replacer, space);\n } else {\n result = JSON.stringify(value, null, space);\n }\n\n // JSON.stringify can return undefined for undefined, functions, symbols\n if (result === undefined) {\n throw new TypeError('Unable to stringify value');\n }\n\n return result;\n }\n\n /**\n * Deep clone via JSON round-trip\n */\n clone<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n }\n\n /**\n * Parse without throwing\n */\n safeParse<T = unknown>(text: string): Result<T, ParseError> {\n try {\n const value = JSON.parse(text) as T;\n return { success: true, value };\n } catch (e) {\n const error = e as Error;\n const parseError: ParseError = {\n message: error.message,\n };\n\n // Try to extract position from error message\n const posMatch = error.message.match(/position (\\d+)/i);\n if (posMatch) {\n // Calculate line and column from position\n const position = parseInt(posMatch[1], 10);\n let line = 1;\n let column = 1;\n for (let i = 0; i < position && i < text.length; i++) {\n if (text[i] === '\\n') {\n line++;\n column = 1;\n } else {\n column++;\n }\n }\n parseError.line = line;\n parseError.column = column;\n }\n\n return { success: false, error: parseError };\n }\n }\n\n /**\n * Stringify without throwing\n */\n safeStringify(value: unknown): Result<string, StringifyError> {\n try {\n const result = JSON.stringify(value);\n if (result === undefined) {\n return {\n success: false,\n error: { message: 'Unable to stringify value' },\n };\n }\n return { success: true, value: result };\n } catch (e) {\n const error = e as Error;\n return {\n success: false,\n error: { message: error.message },\n };\n }\n }\n\n /**\n * Validate JSON string\n */\n isValid(text: string): boolean {\n try {\n JSON.parse(text);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get adapter information\n */\n getInfo(): AdapterInfo {\n return {\n name: 'native',\n isNative: true,\n version: typeof process !== 'undefined' ? process.version : 'unknown',\n simdEnabled: false,\n };\n }\n}\n\n/**\n * Singleton instance of the native adapter\n */\nexport const nativeAdapter = new NativeAdapter();\n","/**\n * Sonic (Rust SIMD) JSON adapter\n *\n * This adapter uses sonic-rs through napi-rs bindings for\n * SIMD-accelerated JSON parsing and serialization.\n */\n\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type {\n AdapterInfo,\n JSONAdapter,\n NativeBindings,\n ParseError,\n Replacer,\n Result,\n Reviver,\n StringifyError,\n} from '../types.js';\n\n// Create require function for loading native modules\nconst require = createRequire(import.meta.url);\n\n/**\n * Try to load the native bindings\n * Returns null if not available (no Rust binary for this platform)\n */\nfunction tryLoadNative(): NativeBindings | null {\n // Get the directory of this file\n const Filename = fileURLToPath(import.meta.url);\n const Dirname = dirname(Filename);\n\n // Try various paths where the native module might be\n const paths = [\n join(Dirname, '..', '..', 'json-native.node'), // dist/../json-native.node\n join(Dirname, '..', 'json-native.node'), // dist/json-native.node\n join(Dirname, 'json-native.node'), // In same directory\n ];\n\n for (const modulePath of paths) {\n try {\n const native = require(modulePath);\n return native as NativeBindings;\n } catch {\n // Try next path\n }\n }\n\n return null;\n}\n\n/**\n * Sonic (Rust SIMD) JSON adapter implementation\n *\n * Uses sonic-rs for SIMD-accelerated parsing and serialization.\n * On supported platforms, this can be 2-3x faster than native JSON.\n */\nexport class SonicAdapter implements JSONAdapter {\n readonly name = 'sonic' as const;\n readonly isNative = false;\n\n private native: NativeBindings;\n\n constructor(native: NativeBindings) {\n this.native = native;\n }\n\n /**\n * Parse a JSON string using sonic-rs\n */\n parse<T = unknown>(text: string, reviver?: Reviver): T {\n const result = this.native.parse(text);\n\n // Apply reviver if provided (need to walk the object)\n if (reviver) {\n return this.applyReviver(result, reviver) as T;\n }\n\n return result as T;\n }\n\n /**\n * Stringify a value using sonic-rs\n */\n stringify(\n value: unknown,\n replacer?: Replacer,\n space?: number | string,\n ): string {\n // Apply replacer if provided\n let processedValue = value;\n if (replacer) {\n processedValue = this.applyReplacer(value, replacer);\n }\n\n // Handle spacing\n if (space !== undefined && space !== null && space !== 0 && space !== '') {\n const indent =\n typeof space === 'string'\n ? Math.min(space.length, 10)\n : Math.min(Math.max(0, space), 10);\n return this.native.stringifyPretty(processedValue, indent);\n }\n\n return this.native.stringify(processedValue);\n }\n\n /**\n * Deep clone via sonic-rs round-trip\n */\n clone<T>(value: T): T {\n return this.native.clone(value) as T;\n }\n\n /**\n * Parse without throwing\n */\n safeParse<T = unknown>(text: string): Result<T, ParseError> {\n const result = this.native.parseSafe(text);\n\n if (result.success) {\n return { success: true, value: result.value as T };\n }\n\n const parseError: ParseError = {\n message: result.error || 'Unknown parse error',\n };\n\n if (result.errorPosition) {\n parseError.line = result.errorPosition.line;\n parseError.column = result.errorPosition.column;\n }\n\n return { success: false, error: parseError };\n }\n\n /**\n * Stringify without throwing\n */\n safeStringify(value: unknown): Result<string, StringifyError> {\n const result = this.native.stringifySafe(value);\n\n if (result.success && result.value !== undefined) {\n return { success: true, value: result.value };\n }\n\n return {\n success: false,\n error: { message: result.error || 'Unknown stringify error' },\n };\n }\n\n /**\n * Validate JSON string using sonic-rs\n */\n isValid(text: string): boolean {\n return this.native.isValid(text);\n }\n\n /**\n * Get adapter information\n */\n getInfo(): AdapterInfo {\n const info = this.native.getAdapterInfo();\n return {\n name: 'sonic',\n isNative: false,\n version: info.version,\n simdEnabled: info.simdEnabled,\n };\n }\n\n /**\n * Apply reviver function to parsed value\n * @internal\n */\n private applyReviver(value: unknown, reviver: Reviver): unknown {\n // Walk the object tree and apply reviver\n return this.walkReviver({ '': value }, '', reviver);\n }\n\n private walkReviver(\n holder: Record<string, unknown>,\n key: string,\n reviver: Reviver,\n ): unknown {\n const value = holder[key];\n\n if (value && typeof value === 'object') {\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const newValue = this.walkReviver(\n value as unknown as Record<string, unknown>,\n String(i),\n reviver,\n );\n if (newValue === undefined) {\n value.splice(i, 1);\n i--;\n } else {\n value[i] = newValue;\n }\n }\n } else {\n for (const k of Object.keys(value)) {\n const newValue = this.walkReviver(\n value as Record<string, unknown>,\n k,\n reviver,\n );\n if (newValue === undefined) {\n delete (value as Record<string, unknown>)[k];\n } else {\n (value as Record<string, unknown>)[k] = newValue;\n }\n }\n }\n }\n\n return reviver.call(holder, key, value);\n }\n\n /**\n * Apply replacer to value before stringifying\n * @internal\n */\n private applyReplacer(value: unknown, replacer: Replacer): unknown {\n if (Array.isArray(replacer)) {\n // Filter object keys\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const filtered: Record<string, unknown> = {};\n for (const key of replacer) {\n const k = String(key);\n if (k in (value as Record<string, unknown>)) {\n filtered[k] = (value as Record<string, unknown>)[k];\n }\n }\n return filtered;\n }\n return value;\n }\n\n if (typeof replacer === 'function') {\n // Apply replacer function\n return this.walkReplacer({ '': value }, '', replacer);\n }\n\n return value;\n }\n\n private walkReplacer(\n holder: Record<string, unknown>,\n key: string,\n replacer: (key: string, value: unknown) => unknown,\n ): unknown {\n let value = holder[key];\n value = replacer.call(holder, key, value);\n\n if (value && typeof value === 'object') {\n if (Array.isArray(value)) {\n const arr: unknown[] = [];\n for (let i = 0; i < value.length; i++) {\n const item = this.walkReplacer(\n value as unknown as Record<string, unknown>,\n String(i),\n replacer,\n );\n arr.push(item);\n }\n return arr;\n } else {\n const obj: Record<string, unknown> = {};\n for (const k of Object.keys(value)) {\n const item = this.walkReplacer(\n value as Record<string, unknown>,\n k,\n replacer,\n );\n if (item !== undefined) {\n obj[k] = item;\n }\n }\n return obj;\n }\n }\n\n return value;\n }\n}\n\n/**\n * Try to create a SonicAdapter instance\n * Returns null if native bindings are not available\n */\nexport function createSonicAdapter(): SonicAdapter | null {\n const native = tryLoadNative();\n if (native) {\n return new SonicAdapter(native);\n }\n return null;\n}\n\n/**\n * Check if sonic (Rust) adapter is available on this platform\n */\nexport function isSonicAvailable(): boolean {\n return tryLoadNative() !== null;\n}\n"],"names":["require"],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { AdapterType, JSONAdapter, JSONOptions } from './types.js';
2
+ /**
3
+ * Factory for creating JSON adapters
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * // Auto-select best available adapter
8
+ * const json = JSONFactory.create();
9
+ *
10
+ * // Force native adapter
11
+ * const native = JSONFactory.create({ adapter: 'native' });
12
+ *
13
+ * // Force sonic, throw if unavailable
14
+ * const sonic = JSONFactory.create({ adapter: 'sonic', fallback: false });
15
+ * ```
16
+ */
17
+ export declare class JSONFactory {
18
+ /**
19
+ * Create a new JSON adapter instance
20
+ *
21
+ * @param options - Configuration options
22
+ * @returns A JSON adapter instance
23
+ * @throws Error if requested adapter is unavailable and fallback is false
24
+ */
25
+ static create(options?: JSONOptions): JSONAdapter;
26
+ /**
27
+ * Get the default adapter instance (cached singleton)
28
+ *
29
+ * Uses 'auto' mode to select the best available adapter.
30
+ * The instance is cached for subsequent calls.
31
+ */
32
+ static getDefault(): JSONAdapter;
33
+ /**
34
+ * Reset the default adapter (useful for testing)
35
+ * @internal
36
+ */
37
+ static resetDefault(): void;
38
+ /**
39
+ * Check if a specific adapter type is available
40
+ */
41
+ static isAvailable(adapter: AdapterType): boolean;
42
+ /**
43
+ * Get the name of the adapter that would be used with given options
44
+ */
45
+ static getAdapterName(options?: JSONOptions): 'sonic' | 'native';
46
+ }
47
+ /**
48
+ * Get the default JSON adapter
49
+ *
50
+ * Convenience function that returns JSONFactory.getDefault()
51
+ */
52
+ export declare function getDefaultAdapter(): JSONAdapter;
53
+ /**
54
+ * Create a new JSON adapter
55
+ *
56
+ * Convenience function that calls JSONFactory.create()
57
+ */
58
+ export declare function createAdapter(options?: JSONOptions): JSONAdapter;
59
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAOxE;;;;;;;;;;;;;;GAcG;AACH,qBAAa,WAAW;IACtB;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,GAAE,WAAgB,GAAG,WAAW;IAmCrD;;;;;OAKG;IACH,MAAM,CAAC,UAAU,IAAI,WAAW;IAOhC;;;OAGG;IACH,MAAM,CAAC,YAAY,IAAI,IAAI;IAI3B;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO;IAcjD;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,GAAG,QAAQ;CAarE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,CAEhE"}
@@ -0,0 +1,181 @@
1
+ import { ParseError, Replacer, Result, Reviver, StringifyError } from './types.js';
2
+ /**
3
+ * @happyvertical/json
4
+ *
5
+ * High-performance JSON parsing and serialization with Rust SIMD acceleration
6
+ * and automatic fallback to native JavaScript.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { parse, stringify, clone } from '@happyvertical/json';
11
+ *
12
+ * // Drop-in replacements for JSON.parse/stringify
13
+ * const data = parse<MyType>('{"key": "value"}');
14
+ * const json = stringify(data);
15
+ *
16
+ * // Deep clone (optimized)
17
+ * const copy = clone(data);
18
+ *
19
+ * // Safe variants (don't throw)
20
+ * const result = safeParse<MyType>(maybeInvalidJson);
21
+ * if (result.success) {
22
+ * console.log(result.value);
23
+ * } else {
24
+ * console.error(result.error.message);
25
+ * }
26
+ * ```
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * import { JSONFactory } from '@happyvertical/json';
31
+ *
32
+ * // Create adapter with specific options
33
+ * const json = JSONFactory.create({ adapter: 'sonic', fallback: true });
34
+ *
35
+ * // Check adapter info
36
+ * console.log(json.name); // 'sonic' or 'native'
37
+ * console.log(json.isNative); // false if using Rust
38
+ * ```
39
+ *
40
+ * @packageDocumentation
41
+ */
42
+ export { createSonicAdapter, isSonicAvailable, NativeAdapter, nativeAdapter, SonicAdapter, } from './adapters/index.js';
43
+ export { createAdapter, getDefaultAdapter, JSONFactory } from './factory.js';
44
+ export type { AdapterInfo, AdapterType, JSONAdapter, JSONOptions, ParseError, Replacer, Result, Reviver, StringifyError, } from './types.js';
45
+ /**
46
+ * Parse a JSON string into a JavaScript value
47
+ *
48
+ * Drop-in replacement for JSON.parse with optional SIMD acceleration.
49
+ *
50
+ * @param text - The JSON string to parse
51
+ * @param reviver - Optional function to transform values during parsing
52
+ * @returns The parsed JavaScript value
53
+ * @throws {SyntaxError} If the input is not valid JSON
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const data = parse<User>('{"name": "Alice", "age": 30}');
58
+ * console.log(data.name); // "Alice"
59
+ * ```
60
+ */
61
+ export declare function parse<T = unknown>(text: string, reviver?: Reviver): T;
62
+ /**
63
+ * Convert a JavaScript value to a JSON string
64
+ *
65
+ * Drop-in replacement for JSON.stringify with optional SIMD acceleration.
66
+ *
67
+ * @param value - The value to stringify
68
+ * @param replacer - Optional function or array to filter/transform values
69
+ * @param space - Number of spaces for indentation (0-10) or string
70
+ * @returns The JSON string
71
+ * @throws {TypeError} If the value contains circular references or BigInt
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const json = stringify({ name: "Alice", age: 30 });
76
+ * console.log(json); // '{"name":"Alice","age":30}'
77
+ *
78
+ * // With pretty printing
79
+ * const pretty = stringify(data, null, 2);
80
+ * ```
81
+ */
82
+ export declare function stringify(value: unknown, replacer?: Replacer, space?: number | string): string;
83
+ /**
84
+ * Deep clone a value via JSON round-trip
85
+ *
86
+ * Optimized alternative to JSON.parse(JSON.stringify(value)).
87
+ * Note: Only clones JSON-serializable values (no functions, symbols, etc).
88
+ *
89
+ * @param value - The value to clone
90
+ * @returns A deep clone of the value
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const original = { nested: { deep: [1, 2, 3] } };
95
+ * const copy = clone(original);
96
+ * copy.nested.deep.push(4);
97
+ * console.log(original.nested.deep); // [1, 2, 3] - unchanged
98
+ * ```
99
+ */
100
+ export declare function clone<T>(value: T): T;
101
+ /**
102
+ * Parse a JSON string without throwing on errors
103
+ *
104
+ * Returns a Result type with either the parsed value or error details.
105
+ *
106
+ * @param text - The JSON string to parse
107
+ * @returns A Result object with either the parsed value or error details
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * const result = safeParse<User>(userInput);
112
+ * if (result.success) {
113
+ * console.log(result.value.name);
114
+ * } else {
115
+ * console.error(`Parse error at line ${result.error.line}: ${result.error.message}`);
116
+ * }
117
+ * ```
118
+ */
119
+ export declare function safeParse<T = unknown>(text: string): Result<T, ParseError>;
120
+ /**
121
+ * Stringify a value without throwing on errors
122
+ *
123
+ * Returns a Result type with either the JSON string or error details.
124
+ *
125
+ * @param value - The value to stringify
126
+ * @returns A Result object with either the JSON string or error details
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const result = safeStringify(data);
131
+ * if (result.success) {
132
+ * console.log(result.value);
133
+ * } else {
134
+ * console.error(`Stringify error: ${result.error.message}`);
135
+ * }
136
+ * ```
137
+ */
138
+ export declare function safeStringify(value: unknown): Result<string, StringifyError>;
139
+ /**
140
+ * Check if a string is valid JSON without parsing
141
+ *
142
+ * Faster than try/catch with parse() when you only need validation.
143
+ *
144
+ * @param text - The string to validate
145
+ * @returns true if the string is valid JSON
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * if (isValid(userInput)) {
150
+ * const data = parse(userInput);
151
+ * }
152
+ * ```
153
+ */
154
+ export declare function isValid(text: string): boolean;
155
+ /**
156
+ * Get information about the current JSON adapter
157
+ *
158
+ * @returns Adapter information including name, version, and SIMD status
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * const info = getAdapterInfo();
163
+ * console.log(`Using ${info.name} adapter`);
164
+ * console.log(`SIMD enabled: ${info.simdEnabled}`);
165
+ * ```
166
+ */
167
+ export declare function getAdapterInfo(): import('./types.js').AdapterInfo;
168
+ /**
169
+ * Check if SIMD-accelerated parsing is available
170
+ *
171
+ * @returns true if the Rust SIMD adapter is loaded
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * if (isSIMDAvailable()) {
176
+ * console.log('Using SIMD-accelerated JSON parsing');
177
+ * }
178
+ * ```
179
+ */
180
+ export declare function isSIMDAvailable(): boolean;
181
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE7E,YAAY,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,QAAQ,EACR,MAAM,EACN,OAAO,EACP,cAAc,GACf,MAAM,YAAY,CAAC;AAIpB,OAAO,KAAK,EACV,UAAU,EACV,QAAQ,EACR,MAAM,EACN,OAAO,EACP,cAAc,EACf,MAAM,YAAY,CAAC;AAMpB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAErE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,QAAQ,EACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GACtB,MAAM,CAER;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAEpC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAE1E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAE5E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,qCAE7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC"}
package/dist/index.js ADDED
@@ -0,0 +1,131 @@
1
+ import { N as NativeAdapter, c as createSonicAdapter, i as isSonicAvailable } from "./chunks/sonic-BVfKq74R.js";
2
+ import { S, n } from "./chunks/sonic-BVfKq74R.js";
3
+ let defaultAdapter = null;
4
+ class JSONFactory {
5
+ /**
6
+ * Create a new JSON adapter instance
7
+ *
8
+ * @param options - Configuration options
9
+ * @returns A JSON adapter instance
10
+ * @throws Error if requested adapter is unavailable and fallback is false
11
+ */
12
+ static create(options = {}) {
13
+ const { adapter = "auto", fallback = true } = options;
14
+ if (adapter === "native") {
15
+ return new NativeAdapter();
16
+ }
17
+ if (adapter === "auto" || adapter === "sonic" || adapter === "simd") {
18
+ const sonicAdapter = createSonicAdapter();
19
+ if (sonicAdapter) {
20
+ return sonicAdapter;
21
+ }
22
+ if (adapter !== "auto" && !fallback) {
23
+ throw new Error(
24
+ `Sonic adapter is not available on this platform. Set fallback: true to use native JSON, or use adapter: 'native'.`
25
+ );
26
+ }
27
+ return new NativeAdapter();
28
+ }
29
+ throw new Error(
30
+ `Unknown adapter type: ${adapter}. Valid options are: 'auto', 'sonic', 'simd', 'native'.`
31
+ );
32
+ }
33
+ /**
34
+ * Get the default adapter instance (cached singleton)
35
+ *
36
+ * Uses 'auto' mode to select the best available adapter.
37
+ * The instance is cached for subsequent calls.
38
+ */
39
+ static getDefault() {
40
+ if (!defaultAdapter) {
41
+ defaultAdapter = JSONFactory.create({ adapter: "auto", fallback: true });
42
+ }
43
+ return defaultAdapter;
44
+ }
45
+ /**
46
+ * Reset the default adapter (useful for testing)
47
+ * @internal
48
+ */
49
+ static resetDefault() {
50
+ defaultAdapter = null;
51
+ }
52
+ /**
53
+ * Check if a specific adapter type is available
54
+ */
55
+ static isAvailable(adapter) {
56
+ switch (adapter) {
57
+ case "native":
58
+ return true;
59
+ case "sonic":
60
+ case "simd":
61
+ return isSonicAvailable();
62
+ case "auto":
63
+ return true;
64
+ // Always available (falls back to native)
65
+ default:
66
+ return false;
67
+ }
68
+ }
69
+ /**
70
+ * Get the name of the adapter that would be used with given options
71
+ */
72
+ static getAdapterName(options = {}) {
73
+ const { adapter = "auto" } = options;
74
+ if (adapter === "native") {
75
+ return "native";
76
+ }
77
+ if (isSonicAvailable()) {
78
+ return "sonic";
79
+ }
80
+ return "native";
81
+ }
82
+ }
83
+ function getDefaultAdapter() {
84
+ return JSONFactory.getDefault();
85
+ }
86
+ function createAdapter(options) {
87
+ return JSONFactory.create(options);
88
+ }
89
+ function parse(text, reviver) {
90
+ return getDefaultAdapter().parse(text, reviver);
91
+ }
92
+ function stringify(value, replacer, space) {
93
+ return getDefaultAdapter().stringify(value, replacer, space);
94
+ }
95
+ function clone(value) {
96
+ return getDefaultAdapter().clone(value);
97
+ }
98
+ function safeParse(text) {
99
+ return getDefaultAdapter().safeParse(text);
100
+ }
101
+ function safeStringify(value) {
102
+ return getDefaultAdapter().safeStringify(value);
103
+ }
104
+ function isValid(text) {
105
+ return getDefaultAdapter().isValid(text);
106
+ }
107
+ function getAdapterInfo() {
108
+ return getDefaultAdapter().getInfo();
109
+ }
110
+ function isSIMDAvailable() {
111
+ return !getDefaultAdapter().isNative;
112
+ }
113
+ export {
114
+ JSONFactory,
115
+ NativeAdapter,
116
+ S as SonicAdapter,
117
+ clone,
118
+ createAdapter,
119
+ createSonicAdapter,
120
+ getAdapterInfo,
121
+ getDefaultAdapter,
122
+ isSIMDAvailable,
123
+ isSonicAvailable,
124
+ isValid,
125
+ n as nativeAdapter,
126
+ parse,
127
+ safeParse,
128
+ safeStringify,
129
+ stringify
130
+ };
131
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/factory.ts","../src/index.ts"],"sourcesContent":["/**\n * JSON Factory\n *\n * Factory for creating JSON adapters with automatic fallback support.\n */\n\nimport { NativeAdapter, nativeAdapter } from './adapters/native.js';\nimport { createSonicAdapter, isSonicAvailable } from './adapters/sonic.js';\nimport type { AdapterType, JSONAdapter, JSONOptions } from './types.js';\n\n/**\n * Cached default adapter instance\n */\nlet defaultAdapter: JSONAdapter | null = null;\n\n/**\n * Factory for creating JSON adapters\n *\n * @example\n * ```typescript\n * // Auto-select best available adapter\n * const json = JSONFactory.create();\n *\n * // Force native adapter\n * const native = JSONFactory.create({ adapter: 'native' });\n *\n * // Force sonic, throw if unavailable\n * const sonic = JSONFactory.create({ adapter: 'sonic', fallback: false });\n * ```\n */\nexport class JSONFactory {\n /**\n * Create a new JSON adapter instance\n *\n * @param options - Configuration options\n * @returns A JSON adapter instance\n * @throws Error if requested adapter is unavailable and fallback is false\n */\n static create(options: JSONOptions = {}): JSONAdapter {\n const { adapter = 'auto', fallback = true } = options;\n\n // Handle explicit native request\n if (adapter === 'native') {\n return new NativeAdapter();\n }\n\n // Handle auto or sonic/simd request\n if (adapter === 'auto' || adapter === 'sonic' || adapter === 'simd') {\n const sonicAdapter = createSonicAdapter();\n\n if (sonicAdapter) {\n return sonicAdapter;\n }\n\n // Sonic not available\n if (adapter !== 'auto' && !fallback) {\n throw new Error(\n `Sonic adapter is not available on this platform. ` +\n `Set fallback: true to use native JSON, or use adapter: 'native'.`,\n );\n }\n\n // Fall back to native\n return new NativeAdapter();\n }\n\n // Unknown adapter type\n throw new Error(\n `Unknown adapter type: ${adapter}. ` +\n `Valid options are: 'auto', 'sonic', 'simd', 'native'.`,\n );\n }\n\n /**\n * Get the default adapter instance (cached singleton)\n *\n * Uses 'auto' mode to select the best available adapter.\n * The instance is cached for subsequent calls.\n */\n static getDefault(): JSONAdapter {\n if (!defaultAdapter) {\n defaultAdapter = JSONFactory.create({ adapter: 'auto', fallback: true });\n }\n return defaultAdapter;\n }\n\n /**\n * Reset the default adapter (useful for testing)\n * @internal\n */\n static resetDefault(): void {\n defaultAdapter = null;\n }\n\n /**\n * Check if a specific adapter type is available\n */\n static isAvailable(adapter: AdapterType): boolean {\n switch (adapter) {\n case 'native':\n return true;\n case 'sonic':\n case 'simd':\n return isSonicAvailable();\n case 'auto':\n return true; // Always available (falls back to native)\n default:\n return false;\n }\n }\n\n /**\n * Get the name of the adapter that would be used with given options\n */\n static getAdapterName(options: JSONOptions = {}): 'sonic' | 'native' {\n const { adapter = 'auto' } = options;\n\n if (adapter === 'native') {\n return 'native';\n }\n\n if (isSonicAvailable()) {\n return 'sonic';\n }\n\n return 'native';\n }\n}\n\n/**\n * Get the default JSON adapter\n *\n * Convenience function that returns JSONFactory.getDefault()\n */\nexport function getDefaultAdapter(): JSONAdapter {\n return JSONFactory.getDefault();\n}\n\n/**\n * Create a new JSON adapter\n *\n * Convenience function that calls JSONFactory.create()\n */\nexport function createAdapter(options?: JSONOptions): JSONAdapter {\n return JSONFactory.create(options);\n}\n","/**\n * @happyvertical/json\n *\n * High-performance JSON parsing and serialization with Rust SIMD acceleration\n * and automatic fallback to native JavaScript.\n *\n * @example\n * ```typescript\n * import { parse, stringify, clone } from '@happyvertical/json';\n *\n * // Drop-in replacements for JSON.parse/stringify\n * const data = parse<MyType>('{\"key\": \"value\"}');\n * const json = stringify(data);\n *\n * // Deep clone (optimized)\n * const copy = clone(data);\n *\n * // Safe variants (don't throw)\n * const result = safeParse<MyType>(maybeInvalidJson);\n * if (result.success) {\n * console.log(result.value);\n * } else {\n * console.error(result.error.message);\n * }\n * ```\n *\n * @example\n * ```typescript\n * import { JSONFactory } from '@happyvertical/json';\n *\n * // Create adapter with specific options\n * const json = JSONFactory.create({ adapter: 'sonic', fallback: true });\n *\n * // Check adapter info\n * console.log(json.name); // 'sonic' or 'native'\n * console.log(json.isNative); // false if using Rust\n * ```\n *\n * @packageDocumentation\n */\n\n// Re-export adapters for advanced use cases\nexport {\n createSonicAdapter,\n isSonicAvailable,\n NativeAdapter,\n nativeAdapter,\n SonicAdapter,\n} from './adapters/index.js';\n\n// Re-export factory\nexport { createAdapter, getDefaultAdapter, JSONFactory } from './factory.js';\n// Re-export types\nexport type {\n AdapterInfo,\n AdapterType,\n JSONAdapter,\n JSONOptions,\n ParseError,\n Replacer,\n Result,\n Reviver,\n StringifyError,\n} from './types.js';\n\n// Import for internal use\nimport { getDefaultAdapter } from './factory.js';\nimport type {\n ParseError,\n Replacer,\n Result,\n Reviver,\n StringifyError,\n} from './types.js';\n\n// =============================================================================\n// Drop-in replacement functions\n// =============================================================================\n\n/**\n * Parse a JSON string into a JavaScript value\n *\n * Drop-in replacement for JSON.parse with optional SIMD acceleration.\n *\n * @param text - The JSON string to parse\n * @param reviver - Optional function to transform values during parsing\n * @returns The parsed JavaScript value\n * @throws {SyntaxError} If the input is not valid JSON\n *\n * @example\n * ```typescript\n * const data = parse<User>('{\"name\": \"Alice\", \"age\": 30}');\n * console.log(data.name); // \"Alice\"\n * ```\n */\nexport function parse<T = unknown>(text: string, reviver?: Reviver): T {\n return getDefaultAdapter().parse<T>(text, reviver);\n}\n\n/**\n * Convert a JavaScript value to a JSON string\n *\n * Drop-in replacement for JSON.stringify with optional SIMD acceleration.\n *\n * @param value - The value to stringify\n * @param replacer - Optional function or array to filter/transform values\n * @param space - Number of spaces for indentation (0-10) or string\n * @returns The JSON string\n * @throws {TypeError} If the value contains circular references or BigInt\n *\n * @example\n * ```typescript\n * const json = stringify({ name: \"Alice\", age: 30 });\n * console.log(json); // '{\"name\":\"Alice\",\"age\":30}'\n *\n * // With pretty printing\n * const pretty = stringify(data, null, 2);\n * ```\n */\nexport function stringify(\n value: unknown,\n replacer?: Replacer,\n space?: number | string,\n): string {\n return getDefaultAdapter().stringify(value, replacer, space);\n}\n\n/**\n * Deep clone a value via JSON round-trip\n *\n * Optimized alternative to JSON.parse(JSON.stringify(value)).\n * Note: Only clones JSON-serializable values (no functions, symbols, etc).\n *\n * @param value - The value to clone\n * @returns A deep clone of the value\n *\n * @example\n * ```typescript\n * const original = { nested: { deep: [1, 2, 3] } };\n * const copy = clone(original);\n * copy.nested.deep.push(4);\n * console.log(original.nested.deep); // [1, 2, 3] - unchanged\n * ```\n */\nexport function clone<T>(value: T): T {\n return getDefaultAdapter().clone(value);\n}\n\n/**\n * Parse a JSON string without throwing on errors\n *\n * Returns a Result type with either the parsed value or error details.\n *\n * @param text - The JSON string to parse\n * @returns A Result object with either the parsed value or error details\n *\n * @example\n * ```typescript\n * const result = safeParse<User>(userInput);\n * if (result.success) {\n * console.log(result.value.name);\n * } else {\n * console.error(`Parse error at line ${result.error.line}: ${result.error.message}`);\n * }\n * ```\n */\nexport function safeParse<T = unknown>(text: string): Result<T, ParseError> {\n return getDefaultAdapter().safeParse<T>(text);\n}\n\n/**\n * Stringify a value without throwing on errors\n *\n * Returns a Result type with either the JSON string or error details.\n *\n * @param value - The value to stringify\n * @returns A Result object with either the JSON string or error details\n *\n * @example\n * ```typescript\n * const result = safeStringify(data);\n * if (result.success) {\n * console.log(result.value);\n * } else {\n * console.error(`Stringify error: ${result.error.message}`);\n * }\n * ```\n */\nexport function safeStringify(value: unknown): Result<string, StringifyError> {\n return getDefaultAdapter().safeStringify(value);\n}\n\n/**\n * Check if a string is valid JSON without parsing\n *\n * Faster than try/catch with parse() when you only need validation.\n *\n * @param text - The string to validate\n * @returns true if the string is valid JSON\n *\n * @example\n * ```typescript\n * if (isValid(userInput)) {\n * const data = parse(userInput);\n * }\n * ```\n */\nexport function isValid(text: string): boolean {\n return getDefaultAdapter().isValid(text);\n}\n\n/**\n * Get information about the current JSON adapter\n *\n * @returns Adapter information including name, version, and SIMD status\n *\n * @example\n * ```typescript\n * const info = getAdapterInfo();\n * console.log(`Using ${info.name} adapter`);\n * console.log(`SIMD enabled: ${info.simdEnabled}`);\n * ```\n */\nexport function getAdapterInfo() {\n return getDefaultAdapter().getInfo();\n}\n\n/**\n * Check if SIMD-accelerated parsing is available\n *\n * @returns true if the Rust SIMD adapter is loaded\n *\n * @example\n * ```typescript\n * if (isSIMDAvailable()) {\n * console.log('Using SIMD-accelerated JSON parsing');\n * }\n * ```\n */\nexport function isSIMDAvailable(): boolean {\n return !getDefaultAdapter().isNative;\n}\n"],"names":["getDefaultAdapter"],"mappings":";;AAaA,IAAI,iBAAqC;AAiBlC,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQvB,OAAO,OAAO,UAAuB,IAAiB;AACpD,UAAM,EAAE,UAAU,QAAQ,WAAW,SAAS;AAG9C,QAAI,YAAY,UAAU;AACxB,aAAO,IAAI,cAAA;AAAA,IACb;AAGA,QAAI,YAAY,UAAU,YAAY,WAAW,YAAY,QAAQ;AACnE,YAAM,eAAe,mBAAA;AAErB,UAAI,cAAc;AAChB,eAAO;AAAA,MACT;AAGA,UAAI,YAAY,UAAU,CAAC,UAAU;AACnC,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAGJ;AAGA,aAAO,IAAI,cAAA;AAAA,IACb;AAGA,UAAM,IAAI;AAAA,MACR,yBAAyB,OAAO;AAAA,IAAA;AAAA,EAGpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,aAA0B;AAC/B,QAAI,CAAC,gBAAgB;AACnB,uBAAiB,YAAY,OAAO,EAAE,SAAS,QAAQ,UAAU,MAAM;AAAA,IACzE;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,eAAqB;AAC1B,qBAAiB;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,YAAY,SAA+B;AAChD,YAAQ,SAAA;AAAA,MACN,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AACH,eAAO,iBAAA;AAAA,MACT,KAAK;AACH,eAAO;AAAA;AAAA,MACT;AACE,eAAO;AAAA,IAAA;AAAA,EAEb;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,eAAe,UAAuB,IAAwB;AACnE,UAAM,EAAE,UAAU,OAAA,IAAW;AAE7B,QAAI,YAAY,UAAU;AACxB,aAAO;AAAA,IACT;AAEA,QAAI,oBAAoB;AACtB,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AACF;AAOO,SAAS,oBAAiC;AAC/C,SAAO,YAAY,WAAA;AACrB;AAOO,SAAS,cAAc,SAAoC;AAChE,SAAO,YAAY,OAAO,OAAO;AACnC;AClDO,SAAS,MAAmB,MAAc,SAAsB;AACrE,SAAOA,kBAAAA,EAAoB,MAAS,MAAM,OAAO;AACnD;AAsBO,SAAS,UACd,OACA,UACA,OACQ;AACR,SAAOA,kBAAAA,EAAoB,UAAU,OAAO,UAAU,KAAK;AAC7D;AAmBO,SAAS,MAAS,OAAa;AACpC,SAAOA,kBAAAA,EAAoB,MAAM,KAAK;AACxC;AAoBO,SAAS,UAAuB,MAAqC;AAC1E,SAAOA,kBAAAA,EAAoB,UAAa,IAAI;AAC9C;AAoBO,SAAS,cAAc,OAAgD;AAC5E,SAAOA,kBAAAA,EAAoB,cAAc,KAAK;AAChD;AAiBO,SAAS,QAAQ,MAAuB;AAC7C,SAAOA,kBAAAA,EAAoB,QAAQ,IAAI;AACzC;AAcO,SAAS,iBAAiB;AAC/B,SAAOA,kBAAAA,EAAoB,QAAA;AAC7B;AAcO,SAAS,kBAA2B;AACzC,SAAO,CAACA,oBAAoB;AAC9B;"}
@@ -0,0 +1,182 @@
1
+ /**
2
+ * @happyvertical/json - TypeScript type definitions
3
+ *
4
+ * High-performance JSON parsing and serialization with Rust SIMD acceleration
5
+ */
6
+ /**
7
+ * Standard JSON reviver function type (same as native JSON.parse)
8
+ */
9
+ export type Reviver = (key: string, value: unknown) => unknown;
10
+ /**
11
+ * Standard JSON replacer function type (same as native JSON.stringify)
12
+ */
13
+ export type Replacer = ((key: string, value: unknown) => unknown) | (string | number)[] | null;
14
+ /**
15
+ * Result type for safe (non-throwing) operations
16
+ */
17
+ export type Result<T, E> = {
18
+ success: true;
19
+ value: T;
20
+ } | {
21
+ success: false;
22
+ error: E;
23
+ };
24
+ /**
25
+ * Error information for parse failures
26
+ */
27
+ export interface ParseError {
28
+ /** Error message */
29
+ message: string;
30
+ /** Line number where error occurred (if available) */
31
+ line?: number;
32
+ /** Column number where error occurred (if available) */
33
+ column?: number;
34
+ }
35
+ /**
36
+ * Error information for stringify failures
37
+ */
38
+ export interface StringifyError {
39
+ /** Error message */
40
+ message: string;
41
+ /** Path to the problematic value (if available) */
42
+ path?: string[];
43
+ }
44
+ /**
45
+ * Adapter selection options
46
+ */
47
+ export type AdapterType = 'sonic' | 'simd' | 'native' | 'auto';
48
+ /**
49
+ * Information about the active JSON adapter
50
+ */
51
+ export interface AdapterInfo {
52
+ /** Name of the adapter */
53
+ name: 'sonic' | 'native';
54
+ /** Whether this is the native JavaScript fallback */
55
+ isNative: boolean;
56
+ /** Version of the underlying library */
57
+ version: string;
58
+ /** Whether SIMD acceleration is available */
59
+ simdEnabled: boolean;
60
+ }
61
+ /**
62
+ * Configuration options for creating a JSON adapter
63
+ */
64
+ export interface JSONOptions {
65
+ /**
66
+ * Which adapter to use
67
+ * - 'sonic': Force Rust sonic-rs adapter (throws if unavailable)
68
+ * - 'simd': Alias for sonic (for API consistency)
69
+ * - 'native': Force native JavaScript JSON
70
+ * - 'auto': Try sonic first, fall back to native (default)
71
+ */
72
+ adapter?: AdapterType;
73
+ /**
74
+ * Whether to fall back to native JSON if the requested adapter is unavailable
75
+ * Only applies when adapter is 'sonic' or 'simd'
76
+ * @default true
77
+ */
78
+ fallback?: boolean;
79
+ }
80
+ /**
81
+ * Interface for JSON adapters
82
+ *
83
+ * All adapters implement this interface, ensuring consistent behavior
84
+ * regardless of the underlying implementation.
85
+ */
86
+ export interface JSONAdapter {
87
+ /**
88
+ * Name of this adapter
89
+ */
90
+ readonly name: 'sonic' | 'native';
91
+ /**
92
+ * Whether this is the native JavaScript implementation
93
+ */
94
+ readonly isNative: boolean;
95
+ /**
96
+ * Parse a JSON string into a JavaScript value
97
+ *
98
+ * @param text - The JSON string to parse
99
+ * @param reviver - Optional function to transform values during parsing
100
+ * @returns The parsed JavaScript value
101
+ * @throws {SyntaxError} If the input is not valid JSON
102
+ */
103
+ parse<T = unknown>(text: string, reviver?: Reviver): T;
104
+ /**
105
+ * Convert a JavaScript value to a JSON string
106
+ *
107
+ * @param value - The value to stringify
108
+ * @param replacer - Optional function or array to filter/transform values
109
+ * @param space - Number of spaces for indentation (0-10) or string
110
+ * @returns The JSON string
111
+ * @throws {TypeError} If the value contains circular references or BigInt
112
+ */
113
+ stringify(value: unknown, replacer?: Replacer, space?: number | string): string;
114
+ /**
115
+ * Deep clone a value via JSON round-trip
116
+ *
117
+ * Equivalent to JSON.parse(JSON.stringify(value)) but optimized.
118
+ * Note: This only clones JSON-serializable values.
119
+ *
120
+ * @param value - The value to clone
121
+ * @returns A deep clone of the value
122
+ */
123
+ clone<T>(value: T): T;
124
+ /**
125
+ * Parse a JSON string without throwing on errors
126
+ *
127
+ * @param text - The JSON string to parse
128
+ * @returns A Result object with either the parsed value or error details
129
+ */
130
+ safeParse<T = unknown>(text: string): Result<T, ParseError>;
131
+ /**
132
+ * Stringify a value without throwing on errors
133
+ *
134
+ * @param value - The value to stringify
135
+ * @returns A Result object with either the JSON string or error details
136
+ */
137
+ safeStringify(value: unknown): Result<string, StringifyError>;
138
+ /**
139
+ * Check if a string is valid JSON without parsing
140
+ *
141
+ * @param text - The string to validate
142
+ * @returns true if the string is valid JSON
143
+ */
144
+ isValid(text: string): boolean;
145
+ /**
146
+ * Get detailed information about this adapter
147
+ */
148
+ getInfo(): AdapterInfo;
149
+ }
150
+ /**
151
+ * Native bindings from the Rust module (when available)
152
+ * @internal
153
+ */
154
+ export interface NativeBindings {
155
+ parse(input: string): unknown;
156
+ parseSafe(input: string): {
157
+ success: boolean;
158
+ value?: unknown;
159
+ error?: string;
160
+ errorPosition?: {
161
+ line: number;
162
+ column: number;
163
+ };
164
+ };
165
+ stringify(value: unknown): string;
166
+ stringifyPretty(value: unknown, indent?: number): string;
167
+ stringifySafe(value: unknown): {
168
+ success: boolean;
169
+ value?: string;
170
+ error?: string;
171
+ };
172
+ clone(value: unknown): unknown;
173
+ isValid(input: string): boolean;
174
+ getType(input: string): string;
175
+ getAdapterInfo(): {
176
+ name: string;
177
+ isNative: boolean;
178
+ version: string;
179
+ simdEnabled: boolean;
180
+ };
181
+ }
182
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,QAAQ,GAChB,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,GAC1C,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GACnB,IAAI,CAAC;AAET;;GAEG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IACnB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC3B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAEjC;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;IAClB,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B;;;;;;;OAOG;IACH,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC;IAEvD;;;;;;;;OAQG;IACH,SAAS,CACP,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,QAAQ,EACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GACtB,MAAM,CAAC;IAEV;;;;;;;;OAQG;IACH,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IAEtB;;;;;OAKG;IACH,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAE5D;;;;;OAKG;IACH,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAE9D;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAE/B;;OAEG;IACH,OAAO,IAAI,WAAW,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG;QACxB,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KAClD,CAAC;IACF,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IAClC,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzD,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG;QAC7B,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,cAAc,IAAI;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;CACH"}