@withmarfa/core 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.
package/index.d.ts ADDED
@@ -0,0 +1,424 @@
1
+ /* auto-generated by NAPI-RS */
2
+ /* eslint-disable */
3
+
4
+ /**
5
+ * Which binding artifact the generated loader actually loaded: `'native'` for
6
+ * a native addon, otherwise the `platformArchABI` of the WASI flavor. Every
7
+ * flavor napi-rs can build is listed, because `NAPI_RS_NATIVE_LIBRARY_PATH`
8
+ * can point the loader at a WASI artifact this package does not build itself.
9
+ */
10
+ export declare const __napiBindingTarget: 'native' | 'wasm32-wasi' | 'wasm32-wasip1'
11
+
12
+ /** A local copy of a slice of one server. */
13
+ export declare class MarfaCore {
14
+ /**
15
+ * Opens a store another process writes, to read it only: never the
16
+ * writer, never a write, and a path with no store is refused.
17
+ */
18
+ static openReader(path: string): MarfaCore
19
+ /** A number that moves each time another process saves to the store. */
20
+ dataVersion(): number
21
+ /**
22
+ * Holds the event stream open on a thread of its own and applies each
23
+ * event as it arrives: `onChange` for each change, then `onEnd` once,
24
+ * with the error that ended it or null where it was stopped. Neither
25
+ * callback keeps the process alive. An `onChange` that throws ends the
26
+ * follow, and `onEnd` is told what it threw, as `listener_threw: …`.
27
+ */
28
+ follow(onChange: (arg: Change) => void, onEnd: (arg: string | undefined | null) => void): Subscription
29
+ /**
30
+ * Opens the file at `path`, creating it when absent. `url` and `key` go
31
+ * together; without them only local reads work.
32
+ */
33
+ static open(path: string, url?: string | undefined | null, key?: string | undefined | null): MarfaCore
34
+ /** Replaces the local copy with the declared types at `tier`. */
35
+ hydrate(types: Array<string>, tier: Tier): Promise<HydrateReport>
36
+ /** Applies every event since the stored cursor. */
37
+ catchUp(): Promise<CatchUpReport>
38
+ list(filters?: ListFilters | undefined | null, sort?: Sort | undefined | null): Array<Item>
39
+ get(id: string): Item | null
40
+ edgesFrom(id: string): Array<Edge>
41
+ search(query: string, filters?: SearchFilters | undefined | null, limit?: number | undefined | null): Array<SearchHit>
42
+ status(): Status
43
+ /**
44
+ * Which handle this process holds: the one that may write, or a second
45
+ * opener that reads and refuses every write.
46
+ */
47
+ heldHandle(): Handle
48
+ /** Writes a new item into the local copy and queues it for the server. */
49
+ createItem(draft: Draft): QueuedWrite
50
+ /** Changes an item in the local copy and queues the change. */
51
+ updateItem(id: string, edit: Edit): QueuedWrite
52
+ /** Moves an item to the bin locally and queues the delete. */
53
+ deleteItem(id: string): QueuedWrite
54
+ /** Takes an item out of the bin locally and queues the restore. */
55
+ restoreItem(id: string): QueuedWrite
56
+ /** Moves an item to another lifecycle state. */
57
+ transitionItem(id: string, state: ItemState): QueuedWrite
58
+ /** Links two items. An edge is its own write. */
59
+ createEdge(draft: EdgeDraft): QueuedWrite
60
+ updateEdge(id: string, edit: EdgeEdit): QueuedWrite
61
+ deleteEdge(id: string): QueuedWrite
62
+ /** Puts one tag on an item, as its own write. */
63
+ addTag(id: string, tag: string): QueuedWrite
64
+ removeTag(id: string, tag: string): QueuedWrite
65
+ /** Writes the item's tags whole, dropping any not named. */
66
+ replaceMetadata(id: string, tags: Array<string>): QueuedWrite
67
+ /** Adds the named tags, leaving the rest. */
68
+ mergeMetadata(id: string, tags: Array<string>): QueuedWrite
69
+ /** Writes one extension namespace, as its own write. */
70
+ writeExtension(id: string, namespace: string, body: Record<string, unknown>): QueuedWrite
71
+ deleteExtension(id: string, namespace: string): QueuedWrite
72
+ /** Every queued write and what became of it. */
73
+ queue(): Array<QueuedWrite>
74
+ /** Sends what the queue holds and records what came back. One pass. */
75
+ drain(): Promise<DrainReport>
76
+ /**
77
+ * Holds a file's bytes beside the working copy and queues their upload.
78
+ * Off the JavaScript thread, because the whole file is copied and
79
+ * hashed.
80
+ */
81
+ putBlob(path: string, mimeType?: string | undefined | null): Promise<QueuedWrite>
82
+ /**
83
+ * Attaches a file to an item: its upload, a file item naming the bytes,
84
+ * and an `attached-to` edge, three queued writes. Off the JavaScript
85
+ * thread, for the reason `putBlob` is.
86
+ */
87
+ attach(id: string, path: string, attachment?: Attachment | undefined | null): Promise<Attached>
88
+ /**
89
+ * Where a blob's bytes are held, fetching them first where this store
90
+ * does not hold them yet. Refused `bytes_absent` where they can be
91
+ * neither read nor fetched.
92
+ */
93
+ blob(hash: string): Promise<string>
94
+ /** Whether a blob's bytes are held beside the store, with no request. */
95
+ blobHeld(hash: string): boolean
96
+ /**
97
+ * The thumbnail an item carries, from the copy with no request; null
98
+ * where its type declares none or it carries none. An item the copy does
99
+ * not hold throws `not_found` naming `not_held`, and a held value that is
100
+ * not a thumbnail throws `decoding` naming the item.
101
+ */
102
+ thumbnail(id: string): Thumbnail | null
103
+ /**
104
+ * Sends a blocked or dead write again, under a fresh idempotency key.
105
+ * Answers whether the row was one a release applies to.
106
+ */
107
+ release(id: string): boolean
108
+ /** Releases every write blocked for one reason, and says how many. */
109
+ releaseReason(reason: BlockedReason): number
110
+ /** Clears the writes the server has answered, and says how many went. */
111
+ forgetAnswered(): number
112
+ }
113
+
114
+ /**
115
+ * A held stream, stopped by `stop` or by being collected. The follow ends
116
+ * within a quarter second of either, and `onEnd` is called once it has.
117
+ */
118
+ export declare class Subscription {
119
+ stop(): void
120
+ }
121
+
122
+ /** The three writes an attachment is, in the order they go out. */
123
+ export interface Attached {
124
+ upload: QueuedWrite
125
+ item: QueuedWrite
126
+ edge: QueuedWrite
127
+ }
128
+
129
+ /**
130
+ * How a file is attached. Every field has a default: the MIME type from the
131
+ * file's extension, the title from its name, the type from the MIME type.
132
+ */
133
+ export interface Attachment {
134
+ mimeType?: string
135
+ title?: string
136
+ type?: string
137
+ tier?: Tier
138
+ }
139
+
140
+ /** Why a `blocked` write has stopped. */
141
+ export declare const enum BlockedReason {
142
+ CredentialRefused = 'credential_refused',
143
+ KeySpent = 'key_spent',
144
+ AncestorUnavailable = 'ancestor_unavailable',
145
+ ConflictUnresolved = 'conflict_unresolved',
146
+ AwaitingDependency = 'awaiting_dependency',
147
+ }
148
+
149
+ export interface CatchUpReport {
150
+ applied: number
151
+ skipped: number
152
+ cursor: string
153
+ reachedHead: boolean
154
+ }
155
+
156
+ /**
157
+ * One event a held stream applied: what it was, what it was about, and the
158
+ * cursor it left.
159
+ */
160
+ export interface Change {
161
+ event: string
162
+ itemId?: string
163
+ edgeId?: string
164
+ cursor: string
165
+ }
166
+
167
+ /** A create, before it is queued. */
168
+ export interface Draft {
169
+ type: string
170
+ id?: string
171
+ properties?: Record<string, unknown>
172
+ /** Each queued as a write of its own, waiting on the create. */
173
+ tags?: Array<string>
174
+ tier?: Tier
175
+ source?: string
176
+ sourceId?: string
177
+ occurredAt?: string
178
+ /**
179
+ * The version this create is conditional on, where its natural key
180
+ * resolves a row the server holds.
181
+ */
182
+ baseVersion?: number
183
+ }
184
+
185
+ /** What a drain did. */
186
+ export interface DrainReport {
187
+ sent: number
188
+ held: number
189
+ verdicts: Array<DrainVerdict>
190
+ /** Why the drain stopped before the queue was empty, where it did. */
191
+ stopped?: string
192
+ /**
193
+ * The sources the server said this credential's key does not claim,
194
+ * where a create naming one was refused for it: every create naming
195
+ * one is blocked `credential_refused` until the key claims it.
196
+ */
197
+ unclaimedSources: Array<string>
198
+ retryAfterSeconds?: number
199
+ }
200
+
201
+ /** What became of one write a drain sent. */
202
+ export interface DrainVerdict {
203
+ id: string
204
+ kind: WriteKind
205
+ itemId?: string
206
+ verdict?: Verdict
207
+ refusals: number
208
+ /**
209
+ * The server answered from its record of this idempotency key rather
210
+ * than writing again.
211
+ */
212
+ replayed: boolean
213
+ }
214
+
215
+ export interface Edge {
216
+ id: string
217
+ sourceId: string
218
+ targetId: string
219
+ edgeType: string
220
+ properties: Record<string, unknown>
221
+ version: number
222
+ createdAt: string
223
+ updatedAt: string
224
+ }
225
+
226
+ /** An edge, before it is queued. */
227
+ export interface EdgeDraft {
228
+ sourceId: string
229
+ targetId: string
230
+ edgeType: string
231
+ properties?: Record<string, unknown>
232
+ id?: string
233
+ }
234
+
235
+ /** A change to an edge's properties, and the version it was read at. */
236
+ export interface EdgeEdit {
237
+ properties: Record<string, unknown>
238
+ baseVersion?: number
239
+ }
240
+
241
+ /** A change to an item, and the version it was read at. */
242
+ export interface Edit {
243
+ /** Whole field values; a device never merges inside a field. */
244
+ properties: Record<string, unknown>
245
+ /** Required: an update naming no version is refused before it is sent. */
246
+ baseVersion?: number
247
+ /** The natural key to move the row to. */
248
+ sourceId?: string
249
+ }
250
+
251
+ /** Which handle this process holds on the store. */
252
+ export declare const enum Handle {
253
+ Writer = 'writer',
254
+ Reader = 'reader',
255
+ }
256
+
257
+ export interface HydrateReport {
258
+ types: Array<string>
259
+ tier: Tier
260
+ items: number
261
+ edges: number
262
+ pages: number
263
+ cursor: string
264
+ }
265
+
266
+ export declare const enum Hydration {
267
+ Never = 'never',
268
+ InProgress = 'in_progress',
269
+ Complete = 'complete',
270
+ Expired = 'expired',
271
+ }
272
+
273
+ export interface Item {
274
+ id: string
275
+ type: string
276
+ properties: Record<string, unknown>
277
+ state: ItemState
278
+ tier?: Tier
279
+ version: number
280
+ schemaVersion: number
281
+ source: string
282
+ sourceId?: string
283
+ occurredAt: string
284
+ createdAt: string
285
+ updatedAt: string
286
+ tags: Array<string>
287
+ }
288
+
289
+ export declare const enum ItemState {
290
+ Active = 'active',
291
+ Archived = 'archived',
292
+ Trashed = 'trashed',
293
+ Revoked = 'revoked',
294
+ }
295
+
296
+ /**
297
+ * Narrowing for a list. Leaving `state` unset answers the active state, as
298
+ * the server does; `allStates` lifts that, and a named state wins.
299
+ */
300
+ export interface ListFilters {
301
+ type?: string
302
+ state?: ItemState
303
+ allStates?: boolean
304
+ tier?: Tier
305
+ tags?: Array<string>
306
+ occurredAfter?: string
307
+ occurredBefore?: string
308
+ limit?: number
309
+ offset?: number
310
+ }
311
+
312
+ /** One queued write and what became of it. */
313
+ export interface QueuedWrite {
314
+ id: string
315
+ kind: WriteKind
316
+ itemId?: string
317
+ targetId?: string
318
+ edgeId?: string
319
+ namespace?: string
320
+ tag?: string
321
+ /** The blob an upload carries, by its hash. */
322
+ blob?: string
323
+ baseVersion?: number
324
+ idempotencyKey: string
325
+ /** The writes this one cannot go without, and is refused with. */
326
+ dependsOn: Array<string>
327
+ /**
328
+ * The write ahead of this one to the same row or edge, which it goes
329
+ * out after and is not refused with.
330
+ */
331
+ follows?: string
332
+ verdict?: Verdict
333
+ /** The server's answer, whole, as it arrived. */
334
+ answer?: string
335
+ refusals: number
336
+ queuedAt: string
337
+ answeredAt?: string
338
+ }
339
+
340
+ /**
341
+ * Narrowing for a search: the state rule a list takes, a type with its
342
+ * subtree, and tags, each read as the list reads it.
343
+ */
344
+ export interface SearchFilters {
345
+ state?: ItemState
346
+ allStates?: boolean
347
+ type?: string
348
+ tags?: Array<string>
349
+ }
350
+
351
+ export interface SearchHit {
352
+ item: Item
353
+ /** Higher is a better match. */
354
+ score: number
355
+ snippet: string
356
+ }
357
+
358
+ export interface Sort {
359
+ field: SortField
360
+ direction: SortDirection
361
+ }
362
+
363
+ export declare const enum SortDirection {
364
+ Asc = 'asc',
365
+ Desc = 'desc',
366
+ }
367
+
368
+ export declare const enum SortField {
369
+ CreatedAt = 'created_at',
370
+ UpdatedAt = 'updated_at',
371
+ OccurredAt = 'occurred_at',
372
+ }
373
+
374
+ export interface Status {
375
+ serverOrigin?: string
376
+ sliceTypes: Array<string>
377
+ sliceTier?: Tier
378
+ eventCursor?: string
379
+ hydration: Hydration
380
+ items: number
381
+ edges: number
382
+ }
383
+
384
+ /** An item's thumbnail: the image's type and its bytes. */
385
+ export interface Thumbnail {
386
+ mimeType: string
387
+ bytes: Buffer
388
+ }
389
+
390
+ export declare const enum Tier {
391
+ Library = 'library',
392
+ Feed = 'feed',
393
+ }
394
+
395
+ /**
396
+ * What the server made of a write: one of six, and absent while the write
397
+ * is unanswered.
398
+ */
399
+ export type Verdict =
400
+ | { verdict: 'accepted' }
401
+ | { verdict: 'merged'; fields: Array<string> }
402
+ | { verdict: 'conflicted'; siblingId: string; fields: Array<string> }
403
+ | { verdict: 'refused'; reason: string }
404
+ | { verdict: 'blocked'; reason: BlockedReason }
405
+ | { verdict: 'dead' }
406
+
407
+ /** The kinds of write a queue holds. */
408
+ export declare const enum WriteKind {
409
+ CreateItem = 'create_item',
410
+ UpdateItem = 'update_item',
411
+ DeleteItem = 'delete_item',
412
+ RestoreItem = 'restore_item',
413
+ TransitionItem = 'transition_item',
414
+ CreateEdge = 'create_edge',
415
+ UpdateEdge = 'update_edge',
416
+ DeleteEdge = 'delete_edge',
417
+ ReplaceMetadata = 'replace_metadata',
418
+ MergeMetadata = 'merge_metadata',
419
+ AddTag = 'add_tag',
420
+ RemoveTag = 'remove_tag',
421
+ WriteExtension = 'write_extension',
422
+ DeleteExtension = 'delete_extension',
423
+ UploadBlob = 'upload_blob',
424
+ }
package/index.js ADDED
@@ -0,0 +1,790 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ /* auto-generated by NAPI-RS */
4
+
5
+ const { readFileSync } = require('fs')
6
+ let nativeBinding = null
7
+ // Which artifact actually loaded. The WASI fallback chain overwrites it with
8
+ // the flavor it resolved; the late native retry below leaves it alone because
9
+ // it only runs while no WASI candidate has been loaded.
10
+ let __napiLoadedBindingTarget = 'native'
11
+ const loadErrors = []
12
+
13
+ const isMusl = () => {
14
+ let musl = false
15
+ if (process.platform === 'linux') {
16
+ musl = isMuslFromFilesystem()
17
+ if (musl === null) {
18
+ musl = isMuslFromReport()
19
+ }
20
+ if (musl === null) {
21
+ musl = isMuslFromChildProcess()
22
+ }
23
+ }
24
+ return musl
25
+ }
26
+
27
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
28
+
29
+ const isMuslFromFilesystem = () => {
30
+ try {
31
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
32
+ } catch {
33
+ return null
34
+ }
35
+ }
36
+
37
+ const isMuslFromReport = () => {
38
+ let report = null
39
+ if (process.report && typeof process.report.getReport === 'function') {
40
+ process.report.excludeNetwork = true
41
+ report = process.report.getReport()
42
+ }
43
+ if (!report) {
44
+ return null
45
+ }
46
+ if (report.header && report.header.glibcVersionRuntime) {
47
+ return false
48
+ }
49
+ if (Array.isArray(report.sharedObjects)) {
50
+ if (report.sharedObjects.some(isFileMusl)) {
51
+ return true
52
+ }
53
+ }
54
+ return false
55
+ }
56
+
57
+ const isMuslFromChildProcess = () => {
58
+ try {
59
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
60
+ } catch (e) {
61
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
62
+ return false
63
+ }
64
+ }
65
+
66
+ function requireNative() {
67
+ if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
68
+ try {
69
+ const overrideBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH)
70
+ // The override may be a generated WASI loader, which already reports its
71
+ // own flavor. Adopt it: `module.exports` aliases this object, so claiming
72
+ // 'native' would both misreport the artifact and overwrite the loader's
73
+ // marker through the alias.
74
+ __napiLoadedBindingTarget =
75
+ overrideBinding && typeof overrideBinding.__napiBindingTarget === 'string'
76
+ ? overrideBinding.__napiBindingTarget
77
+ : 'native'
78
+ return overrideBinding
79
+ } catch (err) {
80
+ loadErrors.push(err)
81
+ }
82
+ } else if (process.platform === 'android') {
83
+ if (process.arch === 'arm64') {
84
+ try {
85
+ return require('./marfa-core.android-arm64.node')
86
+ } catch (e) {
87
+ loadErrors.push(e)
88
+ }
89
+ try {
90
+ const binding = require('@withmarfa/core-android-arm64')
91
+ const bindingPackageVersion = require('@withmarfa/core-android-arm64/package.json').version
92
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
93
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
94
+ }
95
+ return binding
96
+ } catch (e) {
97
+ loadErrors.push(e)
98
+ }
99
+ } else if (process.arch === 'arm') {
100
+ try {
101
+ return require('./marfa-core.android-arm-eabi.node')
102
+ } catch (e) {
103
+ loadErrors.push(e)
104
+ }
105
+ try {
106
+ const binding = require('@withmarfa/core-android-arm-eabi')
107
+ const bindingPackageVersion = require('@withmarfa/core-android-arm-eabi/package.json').version
108
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
109
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
110
+ }
111
+ return binding
112
+ } catch (e) {
113
+ loadErrors.push(e)
114
+ }
115
+ } else {
116
+ loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
117
+ }
118
+ } else if (process.platform === 'win32') {
119
+ if (process.arch === 'x64') {
120
+ if ((process.config && process.config.variables && process.config.variables.shlib_suffix === 'dll.a') || (process.config && process.config.variables && process.config.variables.node_target_type === 'shared_library')) {
121
+ try {
122
+ return require('./marfa-core.win32-x64-gnu.node')
123
+ } catch (e) {
124
+ loadErrors.push(e)
125
+ }
126
+ try {
127
+ const binding = require('@withmarfa/core-win32-x64-gnu')
128
+ const bindingPackageVersion = require('@withmarfa/core-win32-x64-gnu/package.json').version
129
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
130
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
131
+ }
132
+ return binding
133
+ } catch (e) {
134
+ loadErrors.push(e)
135
+ }
136
+ } else {
137
+ try {
138
+ return require('./marfa-core.win32-x64-msvc.node')
139
+ } catch (e) {
140
+ loadErrors.push(e)
141
+ }
142
+ try {
143
+ const binding = require('@withmarfa/core-win32-x64-msvc')
144
+ const bindingPackageVersion = require('@withmarfa/core-win32-x64-msvc/package.json').version
145
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
146
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
147
+ }
148
+ return binding
149
+ } catch (e) {
150
+ loadErrors.push(e)
151
+ }
152
+ }
153
+ } else if (process.arch === 'ia32') {
154
+ try {
155
+ return require('./marfa-core.win32-ia32-msvc.node')
156
+ } catch (e) {
157
+ loadErrors.push(e)
158
+ }
159
+ try {
160
+ const binding = require('@withmarfa/core-win32-ia32-msvc')
161
+ const bindingPackageVersion = require('@withmarfa/core-win32-ia32-msvc/package.json').version
162
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
163
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
164
+ }
165
+ return binding
166
+ } catch (e) {
167
+ loadErrors.push(e)
168
+ }
169
+ } else if (process.arch === 'arm64') {
170
+ try {
171
+ return require('./marfa-core.win32-arm64-msvc.node')
172
+ } catch (e) {
173
+ loadErrors.push(e)
174
+ }
175
+ try {
176
+ const binding = require('@withmarfa/core-win32-arm64-msvc')
177
+ const bindingPackageVersion = require('@withmarfa/core-win32-arm64-msvc/package.json').version
178
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
179
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
180
+ }
181
+ return binding
182
+ } catch (e) {
183
+ loadErrors.push(e)
184
+ }
185
+ } else {
186
+ loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
187
+ }
188
+ } else if (process.platform === 'darwin') {
189
+ try {
190
+ return require('./marfa-core.darwin-universal.node')
191
+ } catch (e) {
192
+ loadErrors.push(e)
193
+ }
194
+ try {
195
+ const binding = require('@withmarfa/core-darwin-universal')
196
+ const bindingPackageVersion = require('@withmarfa/core-darwin-universal/package.json').version
197
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
198
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
199
+ }
200
+ return binding
201
+ } catch (e) {
202
+ loadErrors.push(e)
203
+ }
204
+ if (process.arch === 'x64') {
205
+ try {
206
+ return require('./marfa-core.darwin-x64.node')
207
+ } catch (e) {
208
+ loadErrors.push(e)
209
+ }
210
+ try {
211
+ const binding = require('@withmarfa/core-darwin-x64')
212
+ const bindingPackageVersion = require('@withmarfa/core-darwin-x64/package.json').version
213
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
214
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
215
+ }
216
+ return binding
217
+ } catch (e) {
218
+ loadErrors.push(e)
219
+ }
220
+ } else if (process.arch === 'arm64') {
221
+ try {
222
+ return require('./marfa-core.darwin-arm64.node')
223
+ } catch (e) {
224
+ loadErrors.push(e)
225
+ }
226
+ try {
227
+ const binding = require('@withmarfa/core-darwin-arm64')
228
+ const bindingPackageVersion = require('@withmarfa/core-darwin-arm64/package.json').version
229
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
230
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
231
+ }
232
+ return binding
233
+ } catch (e) {
234
+ loadErrors.push(e)
235
+ }
236
+ } else {
237
+ loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
238
+ }
239
+ } else if (process.platform === 'freebsd') {
240
+ if (process.arch === 'x64') {
241
+ try {
242
+ return require('./marfa-core.freebsd-x64.node')
243
+ } catch (e) {
244
+ loadErrors.push(e)
245
+ }
246
+ try {
247
+ const binding = require('@withmarfa/core-freebsd-x64')
248
+ const bindingPackageVersion = require('@withmarfa/core-freebsd-x64/package.json').version
249
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
250
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
251
+ }
252
+ return binding
253
+ } catch (e) {
254
+ loadErrors.push(e)
255
+ }
256
+ } else if (process.arch === 'arm64') {
257
+ try {
258
+ return require('./marfa-core.freebsd-arm64.node')
259
+ } catch (e) {
260
+ loadErrors.push(e)
261
+ }
262
+ try {
263
+ const binding = require('@withmarfa/core-freebsd-arm64')
264
+ const bindingPackageVersion = require('@withmarfa/core-freebsd-arm64/package.json').version
265
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
266
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
267
+ }
268
+ return binding
269
+ } catch (e) {
270
+ loadErrors.push(e)
271
+ }
272
+ } else {
273
+ loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
274
+ }
275
+ } else if (process.platform === 'linux') {
276
+ if (process.arch === 'x64') {
277
+ if (isMusl()) {
278
+ try {
279
+ return require('./marfa-core.linux-x64-musl.node')
280
+ } catch (e) {
281
+ loadErrors.push(e)
282
+ }
283
+ try {
284
+ const binding = require('@withmarfa/core-linux-x64-musl')
285
+ const bindingPackageVersion = require('@withmarfa/core-linux-x64-musl/package.json').version
286
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
287
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
288
+ }
289
+ return binding
290
+ } catch (e) {
291
+ loadErrors.push(e)
292
+ }
293
+ } else {
294
+ try {
295
+ return require('./marfa-core.linux-x64-gnu.node')
296
+ } catch (e) {
297
+ loadErrors.push(e)
298
+ }
299
+ try {
300
+ const binding = require('@withmarfa/core-linux-x64-gnu')
301
+ const bindingPackageVersion = require('@withmarfa/core-linux-x64-gnu/package.json').version
302
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
303
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
304
+ }
305
+ return binding
306
+ } catch (e) {
307
+ loadErrors.push(e)
308
+ }
309
+ }
310
+ } else if (process.arch === 'arm64') {
311
+ if (isMusl()) {
312
+ try {
313
+ return require('./marfa-core.linux-arm64-musl.node')
314
+ } catch (e) {
315
+ loadErrors.push(e)
316
+ }
317
+ try {
318
+ const binding = require('@withmarfa/core-linux-arm64-musl')
319
+ const bindingPackageVersion = require('@withmarfa/core-linux-arm64-musl/package.json').version
320
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
321
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
322
+ }
323
+ return binding
324
+ } catch (e) {
325
+ loadErrors.push(e)
326
+ }
327
+ } else {
328
+ try {
329
+ return require('./marfa-core.linux-arm64-gnu.node')
330
+ } catch (e) {
331
+ loadErrors.push(e)
332
+ }
333
+ try {
334
+ const binding = require('@withmarfa/core-linux-arm64-gnu')
335
+ const bindingPackageVersion = require('@withmarfa/core-linux-arm64-gnu/package.json').version
336
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
337
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
338
+ }
339
+ return binding
340
+ } catch (e) {
341
+ loadErrors.push(e)
342
+ }
343
+ }
344
+ } else if (process.arch === 'arm') {
345
+ if (isMusl()) {
346
+ try {
347
+ return require('./marfa-core.linux-arm-musleabihf.node')
348
+ } catch (e) {
349
+ loadErrors.push(e)
350
+ }
351
+ try {
352
+ const binding = require('@withmarfa/core-linux-arm-musleabihf')
353
+ const bindingPackageVersion = require('@withmarfa/core-linux-arm-musleabihf/package.json').version
354
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
355
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
356
+ }
357
+ return binding
358
+ } catch (e) {
359
+ loadErrors.push(e)
360
+ }
361
+ } else {
362
+ try {
363
+ return require('./marfa-core.linux-arm-gnueabihf.node')
364
+ } catch (e) {
365
+ loadErrors.push(e)
366
+ }
367
+ try {
368
+ const binding = require('@withmarfa/core-linux-arm-gnueabihf')
369
+ const bindingPackageVersion = require('@withmarfa/core-linux-arm-gnueabihf/package.json').version
370
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
371
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
372
+ }
373
+ return binding
374
+ } catch (e) {
375
+ loadErrors.push(e)
376
+ }
377
+ }
378
+ } else if (process.arch === 'loong64') {
379
+ if (isMusl()) {
380
+ try {
381
+ return require('./marfa-core.linux-loong64-musl.node')
382
+ } catch (e) {
383
+ loadErrors.push(e)
384
+ }
385
+ try {
386
+ const binding = require('@withmarfa/core-linux-loong64-musl')
387
+ const bindingPackageVersion = require('@withmarfa/core-linux-loong64-musl/package.json').version
388
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
389
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
390
+ }
391
+ return binding
392
+ } catch (e) {
393
+ loadErrors.push(e)
394
+ }
395
+ } else {
396
+ try {
397
+ return require('./marfa-core.linux-loong64-gnu.node')
398
+ } catch (e) {
399
+ loadErrors.push(e)
400
+ }
401
+ try {
402
+ const binding = require('@withmarfa/core-linux-loong64-gnu')
403
+ const bindingPackageVersion = require('@withmarfa/core-linux-loong64-gnu/package.json').version
404
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
405
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
406
+ }
407
+ return binding
408
+ } catch (e) {
409
+ loadErrors.push(e)
410
+ }
411
+ }
412
+ } else if (process.arch === 'riscv64') {
413
+ if (isMusl()) {
414
+ try {
415
+ return require('./marfa-core.linux-riscv64-musl.node')
416
+ } catch (e) {
417
+ loadErrors.push(e)
418
+ }
419
+ try {
420
+ const binding = require('@withmarfa/core-linux-riscv64-musl')
421
+ const bindingPackageVersion = require('@withmarfa/core-linux-riscv64-musl/package.json').version
422
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
423
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
424
+ }
425
+ return binding
426
+ } catch (e) {
427
+ loadErrors.push(e)
428
+ }
429
+ } else {
430
+ try {
431
+ return require('./marfa-core.linux-riscv64-gnu.node')
432
+ } catch (e) {
433
+ loadErrors.push(e)
434
+ }
435
+ try {
436
+ const binding = require('@withmarfa/core-linux-riscv64-gnu')
437
+ const bindingPackageVersion = require('@withmarfa/core-linux-riscv64-gnu/package.json').version
438
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
439
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
440
+ }
441
+ return binding
442
+ } catch (e) {
443
+ loadErrors.push(e)
444
+ }
445
+ }
446
+ } else if (process.arch === 'ppc64') {
447
+ try {
448
+ return require('./marfa-core.linux-ppc64-gnu.node')
449
+ } catch (e) {
450
+ loadErrors.push(e)
451
+ }
452
+ try {
453
+ const binding = require('@withmarfa/core-linux-ppc64-gnu')
454
+ const bindingPackageVersion = require('@withmarfa/core-linux-ppc64-gnu/package.json').version
455
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
456
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
457
+ }
458
+ return binding
459
+ } catch (e) {
460
+ loadErrors.push(e)
461
+ }
462
+ } else if (process.arch === 's390x') {
463
+ try {
464
+ return require('./marfa-core.linux-s390x-gnu.node')
465
+ } catch (e) {
466
+ loadErrors.push(e)
467
+ }
468
+ try {
469
+ const binding = require('@withmarfa/core-linux-s390x-gnu')
470
+ const bindingPackageVersion = require('@withmarfa/core-linux-s390x-gnu/package.json').version
471
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
472
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
473
+ }
474
+ return binding
475
+ } catch (e) {
476
+ loadErrors.push(e)
477
+ }
478
+ } else {
479
+ loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
480
+ }
481
+ } else if (process.platform === 'openharmony') {
482
+ if (process.arch === 'arm64') {
483
+ try {
484
+ return require('./marfa-core.openharmony-arm64.node')
485
+ } catch (e) {
486
+ loadErrors.push(e)
487
+ }
488
+ try {
489
+ const binding = require('@withmarfa/core-openharmony-arm64')
490
+ const bindingPackageVersion = require('@withmarfa/core-openharmony-arm64/package.json').version
491
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
492
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
493
+ }
494
+ return binding
495
+ } catch (e) {
496
+ loadErrors.push(e)
497
+ }
498
+ } else if (process.arch === 'x64') {
499
+ try {
500
+ return require('./marfa-core.openharmony-x64.node')
501
+ } catch (e) {
502
+ loadErrors.push(e)
503
+ }
504
+ try {
505
+ const binding = require('@withmarfa/core-openharmony-x64')
506
+ const bindingPackageVersion = require('@withmarfa/core-openharmony-x64/package.json').version
507
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
508
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
509
+ }
510
+ return binding
511
+ } catch (e) {
512
+ loadErrors.push(e)
513
+ }
514
+ } else if (process.arch === 'arm') {
515
+ try {
516
+ return require('./marfa-core.openharmony-arm.node')
517
+ } catch (e) {
518
+ loadErrors.push(e)
519
+ }
520
+ try {
521
+ const binding = require('@withmarfa/core-openharmony-arm')
522
+ const bindingPackageVersion = require('@withmarfa/core-openharmony-arm/package.json').version
523
+ if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
524
+ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
525
+ }
526
+ return binding
527
+ } catch (e) {
528
+ loadErrors.push(e)
529
+ }
530
+ } else {
531
+ loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
532
+ }
533
+ } else {
534
+ loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
535
+ }
536
+ }
537
+
538
+ function createLoadErrorChain(errors) {
539
+ return errors.reduce((previous, current) => {
540
+ let message
541
+ try {
542
+ message =
543
+ current && typeof current.message === 'string'
544
+ ? current.message
545
+ : String(current)
546
+ } catch {
547
+ message = 'Unknown error'
548
+ }
549
+ const error = new Error(message)
550
+ error.cause = previous
551
+ return error
552
+ }, null)
553
+ }
554
+
555
+ // NAPI_RS_FORCE_WASI is a tri-state flag:
556
+ // unset / any other value → native binding preferred, WASI is only a fallback
557
+ // 'true' → prefer WASI, but retain native as a lazy fallback
558
+ // 'error' → require WASI without initializing a native fallback
559
+ // Treating any non-empty string as truthy (the historical behavior) meant
560
+ // NAPI_RS_FORCE_WASI=false, NAPI_RS_FORCE_WASI=0, etc. inadvertently triggered
561
+ // the WASI path, causing ENOENT for packages shipped without a .wasi.cjs file.
562
+ //
563
+ // NAPI_RS_WASI_FLAVOR selects one exact generated flavor and implies strict
564
+ // WASI loading. It never crosses into another flavor or falls back to native.
565
+ const __napiWasiFlavors = ['wasm32-wasi']
566
+ const __napiWasiFlavor = process.env.NAPI_RS_WASI_FLAVOR
567
+ const __napiWasiFlavorRequested =
568
+ typeof __napiWasiFlavor === 'string' && __napiWasiFlavor.length > 0
569
+ if (
570
+ __napiWasiFlavorRequested &&
571
+ __napiWasiFlavors.indexOf(__napiWasiFlavor) === -1
572
+ ) {
573
+ throw new Error(
574
+ 'Unsupported WASI flavor "' +
575
+ __napiWasiFlavor +
576
+ '". Available flavors: ' +
577
+ __napiWasiFlavors.join(', '),
578
+ )
579
+ }
580
+ const forceWasiError = process.env.NAPI_RS_FORCE_WASI === 'error'
581
+ const forceWasi =
582
+ process.env.NAPI_RS_FORCE_WASI === 'true' ||
583
+ forceWasiError ||
584
+ __napiWasiFlavorRequested
585
+
586
+ if (!forceWasi) {
587
+ nativeBinding = requireNative()
588
+ }
589
+
590
+ if (!nativeBinding || forceWasi) {
591
+ let wasiBinding = null
592
+ let wasiBindingLoaded = false
593
+ const wasiBindingErrors = []
594
+ const __napiWasiResolveCandidate = (specifier, isPackage, localArtifacts) => {
595
+ try {
596
+ require.resolve(specifier)
597
+ } catch (resolveError) {
598
+ if (!resolveError || resolveError.code !== 'MODULE_NOT_FOUND') {
599
+ throw resolveError
600
+ }
601
+ if (isPackage) {
602
+ try {
603
+ require.resolve(specifier + '/package.json')
604
+ } catch (packageError) {
605
+ if (packageError && packageError.code === 'MODULE_NOT_FOUND') {
606
+ return resolveError
607
+ }
608
+ // An exports restriction proves the package exists even when its
609
+ // package.json is not public. Preserve the root resolution failure.
610
+ throw resolveError
611
+ }
612
+ // The package exists but its main/export target is broken.
613
+ throw resolveError
614
+ }
615
+ return resolveError
616
+ }
617
+ if (localArtifacts) {
618
+ let artifactError = null
619
+ for (let i = 0; i < localArtifacts.length; i++) {
620
+ try {
621
+ require.resolve(localArtifacts[i])
622
+ return null
623
+ } catch (resolveError) {
624
+ if (!resolveError || resolveError.code !== 'MODULE_NOT_FOUND') {
625
+ throw resolveError
626
+ }
627
+ artifactError = resolveError
628
+ }
629
+ }
630
+ return artifactError
631
+ }
632
+ return null
633
+ }
634
+ if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === 'wasm32-wasi')) {
635
+ let candidateError = null
636
+ let candidateFailed = false
637
+ try {
638
+ candidateError = __napiWasiResolveCandidate('./marfa-core.wasi.cjs', false, ['./marfa-core.wasm32-wasi.debug.wasm', './marfa-core.wasm32-wasi.wasm'])
639
+ candidateFailed = candidateError !== null
640
+ if (!candidateFailed) {
641
+ wasiBinding = require('./marfa-core.wasi.cjs')
642
+ nativeBinding = wasiBinding
643
+ __napiLoadedBindingTarget = 'wasm32-wasi'
644
+ wasiBindingLoaded = true
645
+ }
646
+ } catch (err) {
647
+ candidateError = err
648
+ candidateFailed = true
649
+ }
650
+ if (candidateFailed) {
651
+ wasiBindingErrors.push(candidateError)
652
+ loadErrors.push(candidateError)
653
+ }
654
+ }
655
+ if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === 'wasm32-wasi')) {
656
+ let candidateError = null
657
+ let candidateFailed = false
658
+ try {
659
+ candidateError = __napiWasiResolveCandidate('@withmarfa/core-wasm32-wasi', true, undefined)
660
+ candidateFailed = candidateError !== null
661
+ if (!candidateFailed) {
662
+ if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
663
+ const bindingPackageVersion = require('@withmarfa/core-wasm32-wasi/package.json').version
664
+ if (bindingPackageVersion !== '0.0.1') {
665
+ throw new Error(`WASI binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
666
+ }
667
+ }
668
+ wasiBinding = require('@withmarfa/core-wasm32-wasi')
669
+ nativeBinding = wasiBinding
670
+ __napiLoadedBindingTarget = 'wasm32-wasi'
671
+ wasiBindingLoaded = true
672
+ }
673
+ } catch (err) {
674
+ candidateError = err
675
+ candidateFailed = true
676
+ }
677
+ if (candidateFailed) {
678
+ wasiBindingErrors.push(candidateError)
679
+ loadErrors.push(candidateError)
680
+ }
681
+ }
682
+ if (
683
+ !wasiBindingLoaded &&
684
+ forceWasi &&
685
+ !forceWasiError &&
686
+ !__napiWasiFlavorRequested
687
+ ) {
688
+ nativeBinding = requireNative()
689
+ }
690
+ if ((forceWasiError || __napiWasiFlavorRequested) && !wasiBindingLoaded) {
691
+ const error = new Error(
692
+ __napiWasiFlavorRequested
693
+ ? 'WASI binding for flavor "' + __napiWasiFlavor + '" not found'
694
+ : 'WASI binding not found and NAPI_RS_FORCE_WASI is set to error',
695
+ )
696
+ error.cause = createLoadErrorChain(wasiBindingErrors)
697
+ throw error
698
+ }
699
+ }
700
+
701
+ if (!nativeBinding) {
702
+ if (loadErrors.length > 0) {
703
+ const error = new Error(
704
+ `Cannot find native binding. ` +
705
+ `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
706
+ 'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
707
+ )
708
+ // assign instead of the `new Error(message, { cause })` options form,
709
+ // which Node < 16.9 silently ignores
710
+ error.cause = createLoadErrorChain(loadErrors)
711
+ throw error
712
+ }
713
+ throw new Error(`Failed to load native binding`)
714
+ }
715
+
716
+ function __napiStampBindingTarget(exportsObject, target) {
717
+ if (
718
+ Object.prototype.hasOwnProperty.call(exportsObject, '__napiBindingTarget')
719
+ ) {
720
+ if (exportsObject.__napiBindingTarget === target) {
721
+ // Already ours: the root entry aliases the object it loaded, so a WASI
722
+ // fallback candidate — or a `NAPI_RS_NATIVE_LIBRARY_PATH` override that
723
+ // is a generated loader — arrives already stamped with this same value.
724
+ return target
725
+ }
726
+ const error = new Error(
727
+ '`__napiBindingTarget` is reserved by the generated binding loader, but the loaded binding already exports it. Rename the export, e.g. #[napi(js_name = "...")].',
728
+ )
729
+ error.code = 'ERR_NAPI_BINDING_TARGET_CONFLICT'
730
+ throw error
731
+ }
732
+ if (!Object.isExtensible(exportsObject)) {
733
+ // A `#[napi(module_exports)]` hook may seal or freeze this object
734
+ // (`Object::seal` / `Object::freeze`). Reporting the artifact is metadata,
735
+ // never a reason to fail an otherwise successful load, so the stamp is
736
+ // skipped. What a consumer still sees then follows the entry point: the
737
+ // browser and deferred loaders declare `__napiBindingTarget` at module
738
+ // level and go on reporting it, while the CommonJS entries hand back this
739
+ // very object as `module.exports`, so there the value is absent.
740
+ return target
741
+ }
742
+ try {
743
+ // [[Define]], not [[Set]]: an ordinary assignment walks the prototype
744
+ // chain, so an inherited accessor could swallow the value or throw and
745
+ // fail an otherwise successful load. The descriptor is what a successful
746
+ // assignment would have produced.
747
+ Object.defineProperty(exportsObject, '__napiBindingTarget', {
748
+ configurable: true,
749
+ enumerable: true,
750
+ value: target,
751
+ writable: true,
752
+ })
753
+ } catch {
754
+ // Same rule as the non-extensible skip above: reporting the artifact is
755
+ // metadata, never a reason to fail an otherwise successful load. An exotic
756
+ // object (a Proxy whose defineProperty trap refuses) is skipped, not
757
+ // thrown over.
758
+ }
759
+ // The CommonJS loaders assign this return value so `cjs-module-lexer` — and
760
+ // therefore Node's CJS -> ESM named export detection — can see
761
+ // `__napiBindingTarget` statically.
762
+ return target
763
+ }
764
+ // Stamp before the alias, not after. The guard only reads `nativeBinding`
765
+ // (`hasOwnProperty` plus a comparison), which is safe against any addon
766
+ // accessor; an assignment is not, because a `#[napi(module_exports)]` hook can
767
+ // expose a getter reporting this very value and a setter that throws. So the
768
+ // assignment lands on the loader's own `module.exports`, still the original
769
+ // object here, and the alias below replaces it.
770
+ //
771
+ // The assignment is what keeps the marker a statically visible CommonJS export:
772
+ // `cjs-module-lexer` is Node's CJS -> ESM named export detection, it cannot see
773
+ // a bare call, and the later `module.exports = nativeBinding` does not undo the
774
+ // detection. The assignment itself always succeeds — its target is this
775
+ // loader's own, still extensible `module.exports` — and the alias below then
776
+ // discards the value it wrote. What a consumer reads is whatever the guard put
777
+ // on `nativeBinding`, so on a frozen binding, where the guard skips, the
778
+ // linked import resolves to `undefined`.
779
+ module.exports.__napiBindingTarget = __napiStampBindingTarget(nativeBinding, __napiLoadedBindingTarget)
780
+ module.exports = nativeBinding
781
+ module.exports.MarfaCore = nativeBinding.MarfaCore
782
+ module.exports.Subscription = nativeBinding.Subscription
783
+ module.exports.BlockedReason = nativeBinding.BlockedReason
784
+ module.exports.Handle = nativeBinding.Handle
785
+ module.exports.Hydration = nativeBinding.Hydration
786
+ module.exports.ItemState = nativeBinding.ItemState
787
+ module.exports.SortDirection = nativeBinding.SortDirection
788
+ module.exports.SortField = nativeBinding.SortField
789
+ module.exports.Tier = nativeBinding.Tier
790
+ module.exports.WriteKind = nativeBinding.WriteKind
Binary file
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@withmarfa/core",
3
+ "version": "0.0.1",
4
+ "description": "marfa-core as a Node module.",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/withmarfa/marfa.git",
9
+ "directory": "core/bindings/node"
10
+ },
11
+ "engines": {
12
+ "node": ">=22.12.0"
13
+ },
14
+ "main": "index.js",
15
+ "types": "index.d.ts",
16
+ "napi": {
17
+ "binaryName": "marfa-core"
18
+ },
19
+ "devDependencies": {
20
+ "@napi-rs/cli": "^3",
21
+ "@types/node": "^22.20.4",
22
+ "typescript": "^5.9.3"
23
+ },
24
+ "files": [
25
+ "index.js",
26
+ "index.d.ts",
27
+ "*.node"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "build": "napi build --platform --release",
34
+ "build:debug": "napi build --platform",
35
+ "proof": "node scripts/proof.mjs",
36
+ "check": "tsc -p tsconfig.json",
37
+ "test": "node --expose-gc --test test/*.test.mjs"
38
+ }
39
+ }