@photostructure/sqlite 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE +21 -0
  3. package/README.md +522 -0
  4. package/SECURITY.md +114 -0
  5. package/binding.gyp +94 -0
  6. package/dist/index.cjs +134 -0
  7. package/dist/index.cjs.map +1 -0
  8. package/dist/index.d.cts +408 -0
  9. package/dist/index.d.mts +408 -0
  10. package/dist/index.d.ts +408 -0
  11. package/dist/index.mjs +103 -0
  12. package/dist/index.mjs.map +1 -0
  13. package/package.json +144 -0
  14. package/prebuilds/darwin-arm64/@photostructure+sqlite.glibc.node +0 -0
  15. package/prebuilds/linux-arm64/@photostructure+sqlite.glibc.node +0 -0
  16. package/prebuilds/linux-arm64/@photostructure+sqlite.musl.node +0 -0
  17. package/prebuilds/linux-x64/@photostructure+sqlite.glibc.node +0 -0
  18. package/prebuilds/linux-x64/@photostructure+sqlite.musl.node +0 -0
  19. package/prebuilds/win32-x64/@photostructure+sqlite.glibc.node +0 -0
  20. package/scripts/post-build.mjs +21 -0
  21. package/scripts/prebuild-linux-glibc.sh +108 -0
  22. package/src/aggregate_function.cpp +417 -0
  23. package/src/aggregate_function.h +116 -0
  24. package/src/binding.cpp +160 -0
  25. package/src/dirname.ts +13 -0
  26. package/src/index.ts +465 -0
  27. package/src/shims/base_object-inl.h +8 -0
  28. package/src/shims/base_object.h +50 -0
  29. package/src/shims/debug_utils-inl.h +23 -0
  30. package/src/shims/env-inl.h +19 -0
  31. package/src/shims/memory_tracker-inl.h +17 -0
  32. package/src/shims/napi_extensions.h +73 -0
  33. package/src/shims/node.h +16 -0
  34. package/src/shims/node_errors.h +66 -0
  35. package/src/shims/node_mem-inl.h +8 -0
  36. package/src/shims/node_mem.h +31 -0
  37. package/src/shims/node_url.h +23 -0
  38. package/src/shims/promise_resolver.h +31 -0
  39. package/src/shims/util-inl.h +18 -0
  40. package/src/shims/util.h +101 -0
  41. package/src/sqlite_impl.cpp +2440 -0
  42. package/src/sqlite_impl.h +314 -0
  43. package/src/stack_path.ts +64 -0
  44. package/src/types/node-gyp-build.d.ts +4 -0
  45. package/src/upstream/node_sqlite.cc +2706 -0
  46. package/src/upstream/node_sqlite.h +234 -0
  47. package/src/upstream/sqlite.gyp +38 -0
  48. package/src/upstream/sqlite.js +19 -0
  49. package/src/upstream/sqlite3.c +262809 -0
  50. package/src/upstream/sqlite3.h +13773 -0
  51. package/src/upstream/sqlite3ext.h +723 -0
  52. package/src/user_function.cpp +225 -0
  53. package/src/user_function.h +40 -0
package/src/index.ts ADDED
@@ -0,0 +1,465 @@
1
+ // Load the native binding with support for both CJS and ESM
2
+ import nodeGypBuild from "node-gyp-build";
3
+ import { join } from "node:path";
4
+ import { _dirname } from "./dirname";
5
+
6
+ // Use _dirname() helper that works in both CJS/ESM and Jest
7
+ const binding = nodeGypBuild(join(_dirname(), ".."));
8
+
9
+ /**
10
+ * Configuration options for opening a database.
11
+ * This interface matches Node.js sqlite module's DatabaseSyncOptions.
12
+ */
13
+ export interface DatabaseSyncOptions {
14
+ /** Path to the database file. Use ':memory:' for an in-memory database. */
15
+ readonly location?: string;
16
+ /** If true, the database is opened in read-only mode. @default false */
17
+ readonly readOnly?: boolean;
18
+ /** If true, foreign key constraints are enforced. @default true */
19
+ readonly enableForeignKeyConstraints?: boolean;
20
+ /**
21
+ * If true, double-quoted string literals are allowed.
22
+ *
23
+ * If enabled, double quotes can be misinterpreted as identifiers instead of
24
+ * string literals, leading to confusing errors.
25
+ *
26
+ * **The SQLite documentation strongly recommends avoiding double-quoted
27
+ * strings entirely.**
28
+
29
+ * @see https://sqlite.org/quirks.html#dblquote
30
+ * @default false
31
+ */
32
+ readonly enableDoubleQuotedStringLiterals?: boolean;
33
+ /**
34
+ * Sets the busy timeout in milliseconds.
35
+ * @default 5000
36
+ */
37
+ readonly timeout?: number;
38
+ /** If true, enables loading of SQLite extensions. @default false */
39
+ readonly allowExtension?: boolean;
40
+ }
41
+
42
+ /**
43
+ * Options for creating a prepared statement.
44
+ */
45
+ export interface StatementOptions {
46
+ /** If true, the prepared statement's expandedSQL property will contain the expanded SQL. @default false */
47
+ readonly expandedSQL?: boolean;
48
+ /** If true, anonymous parameters are enabled for the statement. @default false */
49
+ readonly anonymousParameters?: boolean;
50
+ }
51
+
52
+ /**
53
+ * A prepared SQL statement that can be executed multiple times with different parameters.
54
+ * This interface represents an instance of the StatementSync class.
55
+ */
56
+ export interface StatementSyncInstance {
57
+ /** The original SQL source string. */
58
+ readonly sourceSQL: string;
59
+ /** The expanded SQL string with bound parameters, if expandedSQL option was set. */
60
+ readonly expandedSQL: string | undefined;
61
+ /**
62
+ * This method executes a prepared statement and returns an object.
63
+ * @param parameters Optional named and anonymous parameters to bind to the statement.
64
+ * @returns An object with the number of changes and the last insert rowid.
65
+ */
66
+ run(...parameters: any[]): {
67
+ changes: number;
68
+ lastInsertRowid: number | bigint;
69
+ };
70
+ /**
71
+ * This method executes a prepared statement and returns the first result row.
72
+ * @param parameters Optional named and anonymous parameters to bind to the statement.
73
+ * @returns The first row from the query results, or undefined if no rows.
74
+ */
75
+ get(...parameters: any[]): any;
76
+ /**
77
+ * This method executes a prepared statement and returns all results as an array.
78
+ * @param parameters Optional named and anonymous parameters to bind to the statement.
79
+ * @returns An array of row objects from the query results.
80
+ */
81
+ all(...parameters: any[]): any[];
82
+ /**
83
+ * This method executes a prepared statement and returns an iterable iterator of objects.
84
+ * Each object represents a row from the query results.
85
+ * @param parameters Optional named and anonymous parameters to bind to the statement.
86
+ * @returns An iterable iterator of row objects.
87
+ */
88
+ iterate(...parameters: any[]): IterableIterator<any>;
89
+ /**
90
+ * Set whether to read integer values as JavaScript BigInt.
91
+ * @param readBigInts If true, read integers as BigInts. @default false
92
+ */
93
+ setReadBigInts(readBigInts: boolean): void;
94
+ /**
95
+ * Set whether to allow bare named parameters in SQL.
96
+ * @param allowBareNamedParameters If true, allows bare named parameters. @default false
97
+ */
98
+ setAllowBareNamedParameters(allowBareNamedParameters: boolean): void;
99
+ /**
100
+ * Set whether to return results as arrays rather than objects.
101
+ * @param returnArrays If true, return results as arrays. @default false
102
+ */
103
+ setReturnArrays(returnArrays: boolean): void;
104
+ /**
105
+ * Returns an array of objects, each representing a column in the statement's result set.
106
+ * Each object has a 'name' property for the column name and a 'type' property for the SQLite type.
107
+ * @returns Array of column metadata objects.
108
+ */
109
+ columns(): Array<{ name: string; type?: string }>;
110
+ /**
111
+ * Finalizes the prepared statement and releases its resources.
112
+ * Called automatically by Symbol.dispose.
113
+ */
114
+ finalize(): void;
115
+ /** Dispose of the statement resources using the explicit resource management protocol. */
116
+ [Symbol.dispose](): void;
117
+ }
118
+
119
+ export interface UserFunctionOptions {
120
+ /** If `true`, sets the `SQLITE_DETERMINISTIC` flag. @default false */
121
+ readonly deterministic?: boolean;
122
+ /** If `true`, sets the `SQLITE_DIRECTONLY` flag. @default false */
123
+ readonly directOnly?: boolean;
124
+ /** If `true`, converts integer arguments to `BigInt`s. @default false */
125
+ readonly useBigIntArguments?: boolean;
126
+ /** If `true`, allows function to be invoked with variable arguments. @default false */
127
+ readonly varargs?: boolean;
128
+ }
129
+
130
+ export interface AggregateOptions {
131
+ /** The initial value for the aggregation. */
132
+ readonly start?: any;
133
+ /** Function called for each row to update the aggregate state. */
134
+ readonly step: (accumulator: any, ...args: any[]) => any;
135
+ /** Optional function for window function support to reverse a step. */
136
+ readonly inverse?: (accumulator: any, ...args: any[]) => any;
137
+ /** Optional function to compute the final result from the accumulator. */
138
+ readonly result?: (accumulator: any) => any;
139
+ /** If `true`, sets the `SQLITE_DETERMINISTIC` flag. @default false */
140
+ readonly deterministic?: boolean;
141
+ /** If `true`, sets the `SQLITE_DIRECTONLY` flag. @default false */
142
+ readonly directOnly?: boolean;
143
+ /** If `true`, converts integer arguments to `BigInt`s. @default false */
144
+ readonly useBigIntArguments?: boolean;
145
+ /** If `true`, allows function to be invoked with variable arguments. @default false */
146
+ readonly varargs?: boolean;
147
+ }
148
+
149
+ export interface SessionOptions {
150
+ /** The table to track changes for. If omitted, all tables are tracked. */
151
+ readonly table?: string;
152
+ /** The database name. @default "main" */
153
+ readonly db?: string;
154
+ }
155
+
156
+ export interface Session {
157
+ /**
158
+ * Generate a changeset containing all changes recorded by the session.
159
+ * @returns A Buffer containing the changeset data.
160
+ */
161
+ changeset(): Buffer;
162
+ /**
163
+ * Generate a patchset containing all changes recorded by the session.
164
+ * @returns A Buffer containing the patchset data.
165
+ */
166
+ patchset(): Buffer;
167
+ /**
168
+ * Close the session and release its resources.
169
+ */
170
+ close(): void;
171
+ }
172
+
173
+ export interface ChangesetApplyOptions {
174
+ /**
175
+ * Function called when a conflict is detected during changeset application.
176
+ * @param conflictType The type of conflict (SQLITE_CHANGESET_CONFLICT, etc.)
177
+ * @returns One of SQLITE_CHANGESET_OMIT, SQLITE_CHANGESET_REPLACE, or SQLITE_CHANGESET_ABORT
178
+ */
179
+ readonly onConflict?: (conflictType: number) => number;
180
+ /**
181
+ * Function called to filter which tables to apply changes to.
182
+ * @param tableName The name of the table
183
+ * @returns true to include the table, false to skip it
184
+ */
185
+ readonly filter?: (tableName: string) => boolean;
186
+ }
187
+
188
+ /**
189
+ * Represents a SQLite database connection.
190
+ * This interface represents an instance of the DatabaseSync class.
191
+ */
192
+ export interface DatabaseSyncInstance {
193
+ /** Indicates whether the database connection is open. */
194
+ readonly isOpen: boolean;
195
+ /** Indicates whether a transaction is currently active. */
196
+ readonly isTransaction: boolean;
197
+
198
+ /**
199
+ * Opens a database connection. This method is called automatically when creating
200
+ * a DatabaseSync instance, so typically should not be called directly.
201
+ * @param configuration Optional configuration for opening the database.
202
+ */
203
+ open(configuration?: DatabaseSyncOptions): void;
204
+ /**
205
+ * Closes the database connection. This method should be called to ensure that
206
+ * the database connection is properly cleaned up. Once a database is closed,
207
+ * it cannot be used again.
208
+ */
209
+ close(): void;
210
+ /**
211
+ * Returns the location of the database file. For attached databases, you can specify
212
+ * the database name. Returns null for in-memory databases.
213
+ * @param dbName The name of the database. Defaults to 'main' (the primary database).
214
+ * @returns The file path of the database, or null for in-memory databases.
215
+ */
216
+ location(dbName?: string): string | null;
217
+ /**
218
+ * Compiles an SQL statement and returns a StatementSyncInstance object.
219
+ * @param sql The SQL statement to prepare.
220
+ * @param options Optional configuration for the statement.
221
+ * @returns A StatementSyncInstance object that can be executed multiple times.
222
+ */
223
+ prepare(sql: string, options?: StatementOptions): StatementSyncInstance;
224
+ /**
225
+ * This method allows one or more SQL statements to be executed without
226
+ * returning any results. This is useful for commands like CREATE TABLE,
227
+ * INSERT, UPDATE, or DELETE.
228
+ * @param sql The SQL statement(s) to execute.
229
+ */
230
+ exec(sql: string): void;
231
+
232
+ /**
233
+ * This method creates SQLite user-defined functions, wrapping sqlite3_create_function_v2().
234
+ * @param name The name of the SQLite function to create.
235
+ * @param func The JavaScript function to call when the SQLite function is invoked.
236
+ */
237
+ function(name: string, func: Function): void;
238
+ /**
239
+ * This method creates SQLite user-defined functions, wrapping sqlite3_create_function_v2().
240
+ * @param name The name of the SQLite function to create.
241
+ * @param options Optional configuration settings.
242
+ * @param func The JavaScript function to call when the SQLite function is invoked.
243
+ */
244
+ function(name: string, options: UserFunctionOptions, func: Function): void;
245
+
246
+ /**
247
+ * This method creates SQLite aggregate functions, wrapping sqlite3_create_window_function().
248
+ * @param name The name of the SQLite aggregate function to create.
249
+ * @param options Configuration object containing step function and other settings.
250
+ */
251
+ aggregate(name: string, options: AggregateOptions): void;
252
+ /**
253
+ * Create a new session to record database changes.
254
+ * @param options Optional configuration for the session.
255
+ * @returns A Session object for recording changes.
256
+ */
257
+ createSession(options?: SessionOptions): Session;
258
+ /**
259
+ * Apply a changeset to the database.
260
+ * @param changeset The changeset data to apply.
261
+ * @param options Optional configuration for applying the changeset.
262
+ * @returns true if successful, false if aborted.
263
+ */
264
+ applyChangeset(changeset: Buffer, options?: ChangesetApplyOptions): boolean;
265
+ /**
266
+ * Enables or disables the loading of SQLite extensions.
267
+ * @param enable If true, enables extension loading. If false, disables it.
268
+ */
269
+ enableLoadExtension(enable: boolean): void;
270
+ /**
271
+ * Loads an SQLite extension from the specified file path.
272
+ * @param path The path to the extension library.
273
+ * @param entryPoint Optional entry point function name. If not provided, uses the default entry point.
274
+ */
275
+ loadExtension(path: string, entryPoint?: string): void;
276
+
277
+ /**
278
+ * Makes a backup of the database. This method abstracts the sqlite3_backup_init(),
279
+ * sqlite3_backup_step() and sqlite3_backup_finish() functions.
280
+ *
281
+ * The backed-up database can be used normally during the backup process. Mutations
282
+ * coming from the same connection will be reflected in the backup right away.
283
+ * However, mutations from other connections will cause the backup process to restart.
284
+ *
285
+ * @param path The path where the backup will be created. If the file already exists, the contents will be overwritten.
286
+ * @param options Optional configuration for the backup operation.
287
+ * @param options.rate Number of pages to be transmitted in each batch of the backup. @default 100
288
+ * @param options.source Name of the source database. This can be 'main' (the default primary database) or any other database that have been added with ATTACH DATABASE. @default 'main'
289
+ * @param options.target Name of the target database. This can be 'main' (the default primary database) or any other database that have been added with ATTACH DATABASE. @default 'main'
290
+ * @param options.progress Callback function that will be called with the number of pages copied and the total number of pages.
291
+ * @returns A promise that resolves when the backup is completed and rejects if an error occurs.
292
+ *
293
+ * @example
294
+ * // Basic backup
295
+ * await db.backup('./backup.db');
296
+ *
297
+ * @example
298
+ * // Backup with progress
299
+ * await db.backup('./backup.db', {
300
+ * rate: 10,
301
+ * progress: ({ totalPages, remainingPages }) => {
302
+ * console.log(`Progress: ${totalPages - remainingPages}/${totalPages}`);
303
+ * }
304
+ * });
305
+ */
306
+ backup(
307
+ path: string | Buffer | URL,
308
+ options?: {
309
+ rate?: number;
310
+ source?: string;
311
+ target?: string;
312
+ progress?: (info: { totalPages: number; remainingPages: number }) => void;
313
+ },
314
+ ): Promise<number>;
315
+
316
+ /** Dispose of the database resources using the explicit resource management protocol. */
317
+ [Symbol.dispose](): void;
318
+ }
319
+
320
+ /**
321
+ * The main SQLite module interface.
322
+ */
323
+ export interface SqliteModule {
324
+ /**
325
+ * The DatabaseSync class represents a synchronous connection to a SQLite database.
326
+ * All operations are performed synchronously, blocking until completion.
327
+ */
328
+ DatabaseSync: new (
329
+ location?: string | Buffer | URL,
330
+ options?: DatabaseSyncOptions,
331
+ ) => DatabaseSyncInstance;
332
+ /**
333
+ * The StatementSync class represents a synchronous prepared statement.
334
+ * This class should not be instantiated directly; use Database.prepare() instead.
335
+ */
336
+ StatementSync: new (
337
+ database: DatabaseSyncInstance,
338
+ sql: string,
339
+ options?: StatementOptions,
340
+ ) => StatementSyncInstance;
341
+ /**
342
+ * The Session class for recording database changes.
343
+ * This class should not be instantiated directly; use Database.createSession() instead.
344
+ */
345
+ Session: new () => Session;
346
+ /**
347
+ * SQLite constants for various operations and flags.
348
+ */
349
+ constants: {
350
+ /** Open database for reading only. */
351
+ SQLITE_OPEN_READONLY: number;
352
+ /** Open database for reading and writing. */
353
+ SQLITE_OPEN_READWRITE: number;
354
+ /** Create database if it doesn't exist. */
355
+ SQLITE_OPEN_CREATE: number;
356
+ // Changeset constants
357
+ /** Skip conflicting changes. */
358
+ SQLITE_CHANGESET_OMIT: number;
359
+ /** Replace conflicting changes. */
360
+ SQLITE_CHANGESET_REPLACE: number;
361
+ /** Abort on conflict. */
362
+ SQLITE_CHANGESET_ABORT: number;
363
+ /** Data conflict type. */
364
+ SQLITE_CHANGESET_DATA: number;
365
+ /** Row not found conflict. */
366
+ SQLITE_CHANGESET_NOTFOUND: number;
367
+ /** General conflict. */
368
+ SQLITE_CHANGESET_CONFLICT: number;
369
+ /** Constraint violation. */
370
+ SQLITE_CHANGESET_CONSTRAINT: number;
371
+ /** Foreign key constraint violation. */
372
+ SQLITE_CHANGESET_FOREIGN_KEY: number;
373
+ // ... more constants
374
+ };
375
+ }
376
+
377
+ // Add Symbol.dispose to the native classes
378
+ if (binding.DatabaseSync && typeof Symbol.dispose !== "undefined") {
379
+ binding.DatabaseSync.prototype[Symbol.dispose] = function () {
380
+ try {
381
+ this.close();
382
+ } catch {
383
+ // Ignore errors during disposal
384
+ }
385
+ };
386
+ }
387
+
388
+ if (binding.StatementSync && typeof Symbol.dispose !== "undefined") {
389
+ binding.StatementSync.prototype[Symbol.dispose] = function () {
390
+ try {
391
+ this.finalize();
392
+ } catch {
393
+ // Ignore errors during disposal
394
+ }
395
+ };
396
+ }
397
+
398
+ // Export the native binding with TypeScript types
399
+
400
+ /**
401
+ * The DatabaseSync class represents a synchronous connection to a SQLite database.
402
+ * All database operations are performed synchronously, blocking the thread until completion.
403
+ *
404
+ * @example
405
+ * ```typescript
406
+ * import { DatabaseSync } from '@photostructure/sqlite';
407
+ *
408
+ * // Create an in-memory database
409
+ * const db = new DatabaseSync(':memory:');
410
+ *
411
+ * // Create a file-based database
412
+ * const fileDb = new DatabaseSync('./mydata.db');
413
+ *
414
+ * // Create with options
415
+ * const readOnlyDb = new DatabaseSync('./data.db', { readOnly: true });
416
+ * ```
417
+ */
418
+ export const DatabaseSync =
419
+ binding.DatabaseSync as SqliteModule["DatabaseSync"];
420
+
421
+ /**
422
+ * The StatementSync class represents a prepared SQL statement.
423
+ * This class should not be instantiated directly; use DatabaseSync.prepare() instead.
424
+ *
425
+ * @example
426
+ * ```typescript
427
+ * const stmt = db.prepare('SELECT * FROM users WHERE id = ?');
428
+ * const user = stmt.get(123);
429
+ * stmt.finalize();
430
+ * ```
431
+ */
432
+ export const StatementSync =
433
+ binding.StatementSync as SqliteModule["StatementSync"];
434
+
435
+ /**
436
+ * The Session class for recording database changes.
437
+ * This class should not be instantiated directly; use DatabaseSync.createSession() instead.
438
+ *
439
+ * @example
440
+ * ```typescript
441
+ * const session = db.createSession({ table: 'users' });
442
+ * // Make some changes to the users table
443
+ * const changeset = session.changeset();
444
+ * session.close();
445
+ * ```
446
+ */
447
+ export const Session = binding.Session as SqliteModule["Session"];
448
+
449
+ /**
450
+ * SQLite constants for various operations and flags.
451
+ *
452
+ * @example
453
+ * ```typescript
454
+ * import { constants } from '@photostructure/sqlite';
455
+ *
456
+ * const db = new DatabaseSync('./data.db', {
457
+ * readOnly: true,
458
+ * // Uses SQLITE_OPEN_READONLY internally
459
+ * });
460
+ * ```
461
+ */
462
+ export const constants = binding.constants as SqliteModule["constants"];
463
+
464
+ // Default export for CommonJS compatibility
465
+ export default binding as SqliteModule;
@@ -0,0 +1,8 @@
1
+ #ifndef SRC_SHIMS_BASE_OBJECT_INL_H_
2
+ #define SRC_SHIMS_BASE_OBJECT_INL_H_
3
+
4
+ #include "base_object.h"
5
+
6
+ // Inline implementations - mostly empty for now
7
+
8
+ #endif // SRC_SHIMS_BASE_OBJECT_INL_H_
@@ -0,0 +1,50 @@
1
+ #ifndef SRC_SHIMS_BASE_OBJECT_H_
2
+ #define SRC_SHIMS_BASE_OBJECT_H_
3
+
4
+ #include <napi.h>
5
+
6
+ #include <memory>
7
+
8
+ namespace node {
9
+
10
+ // Forward declarations
11
+ class Environment;
12
+ class MemoryTracker;
13
+
14
+ // BaseObject implementation for N-API - simplified for compatibility
15
+ class BaseObject {
16
+ public:
17
+ // Internal field count for V8 compatibility
18
+ static constexpr int kInternalFieldCount = 1;
19
+
20
+ explicit BaseObject(Napi::Env env) : env_(env) {}
21
+ virtual ~BaseObject() = default;
22
+
23
+ Napi::Env env() const { return env_; }
24
+ Environment *env_ptr() const;
25
+
26
+ // Memory tracking interface
27
+ virtual void MemoryInfo(MemoryTracker *tracker) const {}
28
+ virtual size_t SelfSize() const { return sizeof(*this); }
29
+
30
+ // Weak reference management
31
+ void MakeWeak() {
32
+ // N-API handles this automatically
33
+ }
34
+
35
+ void ClearWeak() {
36
+ // N-API handles this automatically
37
+ }
38
+
39
+ protected:
40
+ Napi::Env env_;
41
+ };
42
+
43
+ // Smart pointer types for BaseObject
44
+ template <typename T> using BaseObjectPtr = std::shared_ptr<T>;
45
+
46
+ template <typename T> using BaseObjectWeakPtr = std::weak_ptr<T>;
47
+
48
+ } // namespace node
49
+
50
+ #endif // SRC_SHIMS_BASE_OBJECT_H_
@@ -0,0 +1,23 @@
1
+ #ifndef SRC_SHIMS_DEBUG_UTILS_INL_H_
2
+ #define SRC_SHIMS_DEBUG_UTILS_INL_H_
3
+
4
+ #include <cstdio>
5
+
6
+ namespace node {
7
+
8
+ // Debug utilities
9
+ class Debug {
10
+ public:
11
+ static bool enabled(const char *name) { return false; }
12
+ };
13
+
14
+ // Debug logging macro
15
+ #define DEBUG_LOG(...) \
16
+ do { \
17
+ if (false) \
18
+ std::fprintf(stderr, __VA_ARGS__); \
19
+ } while (0)
20
+
21
+ } // namespace node
22
+
23
+ #endif // SRC_SHIMS_DEBUG_UTILS_INL_H_
@@ -0,0 +1,19 @@
1
+ #ifndef SRC_SHIMS_ENV_INL_H_
2
+ #define SRC_SHIMS_ENV_INL_H_
3
+
4
+ #include <napi.h>
5
+
6
+ namespace node {
7
+
8
+ // Environment stubs
9
+ class Environment {
10
+ public:
11
+ static Environment *GetCurrent(Napi::Env env) {
12
+ static Environment instance;
13
+ return &instance;
14
+ }
15
+ };
16
+
17
+ } // namespace node
18
+
19
+ #endif // SRC_SHIMS_ENV_INL_H_
@@ -0,0 +1,17 @@
1
+ #ifndef SRC_SHIMS_MEMORY_TRACKER_INL_H_
2
+ #define SRC_SHIMS_MEMORY_TRACKER_INL_H_
3
+
4
+ namespace node {
5
+
6
+ // Memory tracking stubs
7
+ class MemoryTracker {
8
+ public:
9
+ template <typename T> void TrackField(const char *, const T &) {}
10
+
11
+ template <typename T>
12
+ void TrackFieldWithSize(const char *, const T &, size_t) {}
13
+ };
14
+
15
+ } // namespace node
16
+
17
+ #endif // SRC_SHIMS_MEMORY_TRACKER_INL_H_
@@ -0,0 +1,73 @@
1
+ #ifndef SRC_SHIMS_NAPI_EXTENSIONS_H_
2
+ #define SRC_SHIMS_NAPI_EXTENSIONS_H_
3
+
4
+ #include <napi.h>
5
+
6
+ #include <string>
7
+ #include <vector>
8
+
9
+ namespace node {
10
+
11
+ // V8 to N-API conversion utilities
12
+ class LocalVector {
13
+ public:
14
+ explicit LocalVector(Napi::Env env) : env_(env) {}
15
+
16
+ void push_back(Napi::Value value) { values_.push_back(value); }
17
+
18
+ size_t size() const { return values_.size(); }
19
+
20
+ Napi::Value operator[](size_t index) const { return values_[index]; }
21
+
22
+ private:
23
+ Napi::Env env_;
24
+ std::vector<Napi::Value> values_;
25
+ };
26
+
27
+ // String utilities
28
+ inline Napi::String FIXED_ONE_BYTE_STRING(Napi::Env env, const char *str) {
29
+ return Napi::String::New(env, str);
30
+ }
31
+
32
+ // Utf8Value replacement
33
+ class Utf8Value {
34
+ public:
35
+ explicit Utf8Value(Napi::Value value) {
36
+ if (value.IsString()) {
37
+ str_ = value.As<Napi::String>().Utf8Value();
38
+ }
39
+ }
40
+
41
+ const char *operator*() const { return str_.c_str(); }
42
+ size_t length() const { return str_.length(); }
43
+
44
+ private:
45
+ std::string str_;
46
+ };
47
+
48
+ // Assertion macros
49
+ #define CHECK_EQ(a, b) \
50
+ do { \
51
+ if ((a) != (b)) { \
52
+ throw std::runtime_error("Assertion failed: " #a " == " #b); \
53
+ } \
54
+ } while (0)
55
+
56
+ // BaseObject unwrapping
57
+ template <typename T> T *ASSIGN_OR_RETURN_UNWRAP(Napi::Value value) {
58
+ if (!value.IsObject())
59
+ return nullptr;
60
+ return T::Unwrap(value.As<Napi::Object>());
61
+ }
62
+
63
+ // Memory info macros (no-op for now)
64
+ #define SET_MEMORY_INFO_NAME(tracker, name) \
65
+ do { \
66
+ } while (0)
67
+ #define SET_SELF_SIZE(tracker, size) \
68
+ do { \
69
+ } while (0)
70
+
71
+ } // namespace node
72
+
73
+ #endif // SRC_SHIMS_NAPI_EXTENSIONS_H_
@@ -0,0 +1,16 @@
1
+ #ifndef SRC_SHIMS_NODE_H_
2
+ #define SRC_SHIMS_NODE_H_
3
+
4
+ #include <napi.h>
5
+
6
+ // Node.js compatibility definitions
7
+ #define NODE_WANT_INTERNALS 1
8
+
9
+ namespace node {
10
+
11
+ // Basic Node.js environment stubs
12
+ class Environment;
13
+
14
+ } // namespace node
15
+
16
+ #endif // SRC_SHIMS_NODE_H_