@remedia/node 0.1.0-dev.2 → 0.1.0-dev.4

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/README.md CHANGED
@@ -34,9 +34,9 @@ Requires Node.js **22.18.0 or newer** (ESM).
34
34
  npm install @remedia/node
35
35
  ```
36
36
 
37
- Install FFmpeg 7 shared libraries separately before importing the package. npm does not install
38
- FFmpeg or compile the addon. Required ABI majors are avcodec 61, avformat 61, avutil 59,
39
- avfilter 10, and swresample 5. libopus is statically included; FFmpeg is dynamically linked.
37
+ Install FFmpeg 9 shared libraries separately before importing the package. npm does not install
38
+ FFmpeg or compile the addon. Required ABI majors are avcodec 63, avformat 63, avutil 61,
39
+ avfilter 12, and swresample 7. libopus is statically included; FFmpeg is dynamically linked.
40
40
 
41
41
  Native runtime CI covers Linux x64/ARM64 glibc, macOS x64/ARM64, Windows x64 MSVC, and
42
42
  FreeBSD x64. Additional build-only packages cover Linux x64/ARM64 musl, Linux ARMv7 hard-float GNU,
package/dist/discord.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { RemediaEventEmitter } from './events.js';
2
- import { PlaybackHooks, type PlayOptions, type SessionLifecycleEvents } from './lifecycle.js';
2
+ import { PlaybackHooks, type PlayOptions, type SessionLifecycleEvents, type CrossfadeOptions, type StageNextOptions, type StageSnapshot } from './lifecycle.js';
3
3
  import { FilterControls } from './filters.js';
4
4
  import type { MediaSource } from './input.js';
5
5
  import type { AudioStreamInfo, PlaybackPosition, PlaybackState, VoiceConnectionState } from './types.js';
@@ -21,6 +21,8 @@ export interface DiscordSessionOptions {
21
21
  volume?: number;
22
22
  /** Trusted raw FFmpeg audio filtergraph; defaults to null. Native syntax validation occurs during backend configuration before playback. */
23
23
  filterGraph?: string | null;
24
+ /** Explicit PCM crossfade opt-in; disabled by default. */
25
+ crossfade?: CrossfadeOptions | false;
24
26
  }
25
27
  /** Cancellation and timeout controls for obtaining credentials and establishing a voice transport. */
26
28
  export interface DiscordConnectOptions {
@@ -113,6 +115,17 @@ export declare class DiscordSession<Metadata = unknown> extends RemediaEventEmit
113
115
  * Pause the current playback without replacing its decoder or source generation.
114
116
  * @returns Resolves when the backend accepts the pause request.
115
117
  */
118
+ /**
119
+ * Prepare one upcoming source without restarting playback or its output.
120
+ * @param source - Fresh media input; Readables and buffers require embedded execution.
121
+ * @param options - Queue occurrence, revision fencing, expiry and locally retained metadata.
122
+ * @returns Preparation snapshot; rejects disabled sessions, stale identities or invalid inputs.
123
+ */
124
+ stageNext(source: MediaSource, options: StageNextOptions<Metadata>): Promise<StageSnapshot>;
125
+ /** Cancel the queued stage and release its input. @returns Resolves after cancellation. */
126
+ clearStage(): Promise<void>;
127
+ /** Current preparation snapshot, or null when no stage is pending. */
128
+ get stagedSource(): StageSnapshot | null;
116
129
  pause(): Promise<void>;
117
130
  /**
118
131
  * Resume paused playback on its existing source generation.
package/dist/discord.js CHANGED
@@ -51,6 +51,7 @@ export class DiscordSession extends RemediaEventEmitter {
51
51
  #disposed = false;
52
52
  #filterGraph = null;
53
53
  #volume = 1;
54
+ #crossfade;
54
55
  #configurationWork = Promise.resolve();
55
56
  #nativeStateTimer;
56
57
  /**
@@ -66,6 +67,7 @@ export class DiscordSession extends RemediaEventEmitter {
66
67
  this.#channelId = validateSnowflake('channelId', options.channelId);
67
68
  this.userId = validateSnowflake('userId', options.userId);
68
69
  validateVolume(options.volume ?? 1);
70
+ this.#crossfade = options.crossfade;
69
71
  if (options.filterGraph !== undefined &&
70
72
  options.filterGraph !== null &&
71
73
  (typeof options.filterGraph !== 'string' || !options.filterGraph.trim()))
@@ -310,6 +312,24 @@ export class DiscordSession extends RemediaEventEmitter {
310
312
  * Pause the current playback without replacing its decoder or source generation.
311
313
  * @returns Resolves when the backend accepts the pause request.
312
314
  */
315
+ /**
316
+ * Prepare one upcoming source without restarting playback or its output.
317
+ * @param source - Fresh media input; Readables and buffers require embedded execution.
318
+ * @param options - Queue occurrence, revision fencing, expiry and locally retained metadata.
319
+ * @returns Preparation snapshot; rejects disabled sessions, stale identities or invalid inputs.
320
+ */
321
+ async stageNext(source, options) {
322
+ await this.#configurationWork;
323
+ return this.#requireExistingPlayback().stageNext(source, options);
324
+ }
325
+ /** Cancel the queued stage and release its input. @returns Resolves after cancellation. */
326
+ clearStage() {
327
+ return this.#requireExistingPlayback().clearStage();
328
+ }
329
+ /** Current preparation snapshot, or null when no stage is pending. */
330
+ get stagedSource() {
331
+ return this.#playback?.stagedSource ?? null;
332
+ }
313
333
  pause() {
314
334
  return this.#requireExistingPlayback().pause();
315
335
  }
@@ -694,6 +714,8 @@ export class DiscordSession extends RemediaEventEmitter {
694
714
  const createdPlayback = new PlaybackSession(this.#native, nativeSession.playbackId, undefined, this.guildId, this.hooks);
695
715
  playback = createdPlayback;
696
716
  this.#playback = createdPlayback;
717
+ if (this.#crossfade)
718
+ createdPlayback.configureCrossfade(this.#crossfade);
697
719
  await this.#serializeConfiguration(async () => {
698
720
  if (this.#playback !== createdPlayback)
699
721
  return;
@@ -1133,6 +1155,41 @@ export class DiscordSession extends RemediaEventEmitter {
1133
1155
  guildId: this.guildId,
1134
1156
  });
1135
1157
  });
1158
+ forward(PlaybackEvent.prepareRequested, (event) => {
1159
+ this.emit(PlaybackEvent.prepareRequested, {
1160
+ ...event,
1161
+ sessionId: this.sessionId,
1162
+ guildId: this.guildId,
1163
+ });
1164
+ });
1165
+ forward(PlaybackEvent.stageReady, (event) => {
1166
+ this.emit(PlaybackEvent.stageReady, {
1167
+ ...event,
1168
+ sessionId: this.sessionId,
1169
+ guildId: this.guildId,
1170
+ });
1171
+ });
1172
+ forward(PlaybackEvent.stageFailed, (event) => {
1173
+ this.emit(PlaybackEvent.stageFailed, {
1174
+ ...event,
1175
+ sessionId: this.sessionId,
1176
+ guildId: this.guildId,
1177
+ });
1178
+ });
1179
+ forward(PlaybackEvent.stageInvalidated, (event) => {
1180
+ this.emit(PlaybackEvent.stageInvalidated, {
1181
+ ...event,
1182
+ sessionId: this.sessionId,
1183
+ guildId: this.guildId,
1184
+ });
1185
+ });
1186
+ forward(PlaybackEvent.transitionCancelled, (event) => {
1187
+ this.emit(PlaybackEvent.transitionCancelled, {
1188
+ ...event,
1189
+ sessionId: this.sessionId,
1190
+ guildId: this.guildId,
1191
+ });
1192
+ });
1136
1193
  this.#playbackSubscriptions = {
1137
1194
  playback,
1138
1195
  detach: () => {
package/dist/index.d.ts CHANGED
@@ -6,4 +6,4 @@ export { PlaybackHooks, PlaybackSessionEvents, RemediaEvents, VoiceSessionEvents
6
6
  export { Remedia, type ProbeOptions, type RemediaOptions } from './remedia.js';
7
7
  export type { MediaSource } from './input.js';
8
8
  export type { AudioStreamInfo, DebugListener, DiagnosticEvent, DiagnosticFieldValue, DiagnosticSeverity, PlaybackPosition, PlaybackState, VoiceConnectionState, } from './types.js';
9
- export type { BeforePlayContext, BeforePlayHook, BeforePlayResult, LifecycleVoiceState, PlayOptions, PlaybackEventIdentity, PlaybackLifecycleEvents, PlaybackSessionEventMap, RemediaLifecycleEvents, SessionLifecycleEvents, VoiceEventIdentity, VoiceLifecycleEvents, } from './lifecycle.js';
9
+ export type { CrossfadeOptions, CrossfadeContinuation, CrossfadeTransition, CrossfadeStageEvent, StageNextOptions, StageSnapshot, BeforePlayContext, BeforePlayHook, BeforePlayResult, LifecycleVoiceState, PlayOptions, PlaybackEventIdentity, PlaybackLifecycleEvents, PlaybackSessionEventMap, RemediaLifecycleEvents, SessionLifecycleEvents, VoiceEventIdentity, VoiceLifecycleEvents, } from './lifecycle.js';
package/dist/input.d.ts CHANGED
@@ -15,7 +15,9 @@ export type MediaSource = {
15
15
  buffer: Buffer | Uint8Array;
16
16
  } | {
17
17
  /**
18
- * Caller-owned binary Readable, consumed with bounded backpressure in embedded mode; Remedia does not destroy it.
18
+ * Caller-owned binary Readable, consumed with bounded backpressure in embedded mode.
19
+ * Playback can seek forward, not backward, without caching prior input.
20
+ * Remedia does not destroy the caller-owned stream.
19
21
  */
20
22
  stream: Readable;
21
23
  };
@@ -16,6 +16,11 @@ export declare const PlaybackSessionEvents: {
16
16
  readonly playbackResumed: "playbackResumed";
17
17
  /** Emitted after seeking to a source timeline position. */
18
18
  readonly playbackSeeked: "playbackSeeked";
19
+ readonly prepareRequested: "prepareRequested";
20
+ readonly stageReady: "stageReady";
21
+ readonly stageFailed: "stageFailed";
22
+ readonly stageInvalidated: "stageInvalidated";
23
+ readonly transitionCancelled: "transitionCancelled";
19
24
  /** Emitted when the configured session filtergraph changes. */
20
25
  readonly filterChanged: "filterChanged";
21
26
  /** Emitted when the configured session linear gain changes. */
@@ -56,6 +61,11 @@ export declare const RemediaEvents: {
56
61
  readonly playbackResumed: "playbackResumed";
57
62
  /** Emitted after seeking to a source timeline position. */
58
63
  readonly playbackSeeked: "playbackSeeked";
64
+ readonly prepareRequested: "prepareRequested";
65
+ readonly stageReady: "stageReady";
66
+ readonly stageFailed: "stageFailed";
67
+ readonly stageInvalidated: "stageInvalidated";
68
+ readonly transitionCancelled: "transitionCancelled";
59
69
  /** Emitted when the configured session filtergraph changes. */
60
70
  readonly filterChanged: "filterChanged";
61
71
  /** Emitted when the configured session linear gain changes. */
@@ -69,6 +79,80 @@ export type RemediaEvents = (typeof RemediaEvents)[keyof typeof RemediaEvents];
69
79
  * Correlation fields identifying the session and source generation that produced a playback event.
70
80
  * @typeParam Metadata - Application-owned metadata attached to playback generations.
71
81
  */
82
+ /** Session opt-in for continuous PCM crossfade playback. */
83
+ export interface CrossfadeOptions {
84
+ /** Explicit enablement; omitted sessions retain ordinary playback. */
85
+ enabled: true;
86
+ /** Overlap duration in milliseconds, 1000–30000; defaults to 5000. */
87
+ durationMs?: number;
88
+ /** Lead before overlap in milliseconds, 5000–120000; defaults to 30000. */
89
+ prepareBeforeMs?: number;
90
+ /** Equal-power curve; the only supported curve. */
91
+ curve?: 'equalPower';
92
+ }
93
+ /** Identify a particular queued occurrence. Revisions prevent stale stage
94
+ * responses from replacing newer queue decisions.
95
+ */
96
+ export interface StageNextOptions<Metadata = unknown> {
97
+ /** Stable ID of this queued occurrence, including repeated tracks. */
98
+ entryId: string;
99
+ /** Monotonically increasing queue decision revision; non-negative safe integer. */
100
+ queueRevision: number;
101
+ /** Revision of the resolved source for this entry; defaults to zero. */
102
+ sourceRevision?: number;
103
+ /** Absolute Unix time in milliseconds after which a prepared source must not be promoted. */
104
+ expiresAtMs?: number;
105
+ /** Current source generation to fence delayed preparation results; defaults to the active generation. */
106
+ expectedGeneration?: number;
107
+ /** Application-owned metadata retained locally and attached to incoming lifecycle events. */
108
+ customMetadata?: Metadata;
109
+ }
110
+ /** Crossfade playback identity, state, or capability metadata. */
111
+ export interface StageSnapshot {
112
+ /** Current source generation to fence delayed preparation results; defaults to the active generation. */
113
+ expectedGeneration: number;
114
+ /** Stable ID of this queued occurrence, including repeated tracks. */
115
+ entryId: string;
116
+ /** Monotonically increasing queue decision revision; non-negative safe integer. */
117
+ queueRevision: number;
118
+ /** Revision of the resolved source for this entry; defaults to zero. */
119
+ sourceRevision: number;
120
+ /** Current preparation state; failed sources cannot be promoted. */
121
+ state: 'preparing' | 'ready' | 'failed';
122
+ /** Decoded PCM currently buffered, in milliseconds; bounded to two seconds. */
123
+ bufferedMs: number;
124
+ /** Selected stream metadata, or null until the decoder opens. */
125
+ info: AudioStreamInfo | null;
126
+ /** Preparation failure message, or null. */
127
+ error: string | null;
128
+ }
129
+ /** Crossfade playback identity, state, or capability metadata. */
130
+ export interface CrossfadeContinuation {
131
+ /** Discriminator identifying this lifecycle transition. */
132
+ type: 'promoted';
133
+ /** Source generation identifying the promoted playback. */
134
+ generation: number;
135
+ /** Stable ID of this queued occurrence, including repeated tracks. */
136
+ entryId: string;
137
+ }
138
+ /** Crossfade playback identity, state, or capability metadata. */
139
+ export interface CrossfadeTransition {
140
+ /** Discriminator identifying this lifecycle transition. */
141
+ type: 'crossfade';
142
+ /** Source generation that remains audible during the fade. */
143
+ outgoingGeneration: number;
144
+ /** Stable ID of this queued occurrence, including repeated tracks. */
145
+ entryId: string;
146
+ }
147
+ /** Crossfade playback identity, state, or capability metadata. */
148
+ export interface CrossfadeStageEvent extends PlaybackEventIdentity {
149
+ /** Stable ID of this queued occurrence, including repeated tracks. */
150
+ entryId: string;
151
+ /** Monotonically increasing queue decision revision; non-negative safe integer. */
152
+ queueRevision: number;
153
+ /** Revision of the resolved source for this entry; defaults to zero. */
154
+ sourceRevision: number;
155
+ }
72
156
  export interface PlaybackEventIdentity<Metadata = unknown> {
73
157
  /** Opaque Remedia session identity used to correlate events; distinct from the Discord bot user ID. */
74
158
  sessionId: string;
@@ -95,6 +179,7 @@ export type PlaybackLifecycleEvents<Metadata = unknown> = {
95
179
  state: 'playing';
96
180
  /** Metadata for the audio stream that started playback. */
97
181
  info: AudioStreamInfo;
182
+ transition?: CrossfadeTransition;
98
183
  }
99
184
  ];
100
185
  /** Emitted when a source generation reaches natural end-of-stream. */
@@ -104,6 +189,7 @@ export type PlaybackLifecycleEvents<Metadata = unknown> = {
104
189
  state: 'completed';
105
190
  /** Latest source and output timeline measurements in milliseconds. */
106
191
  position: PlaybackPosition;
192
+ continuation?: CrossfadeContinuation;
107
193
  }
108
194
  ];
109
195
  /** Emitted when a source generation is explicitly stopped or cancelled. */
@@ -125,6 +211,23 @@ export type PlaybackLifecycleEvents<Metadata = unknown> = {
125
211
  }
126
212
  ];
127
213
  /** Emitted when playback is paused without replacing its source generation. */
214
+ [PlaybackSessionEvents.prepareRequested]: [
215
+ PlaybackEventIdentity<Metadata> & {
216
+ remainingMs: number;
217
+ transitionInMs: number;
218
+ }
219
+ ];
220
+ [PlaybackSessionEvents.stageReady]: [CrossfadeStageEvent];
221
+ [PlaybackSessionEvents.stageFailed]: [CrossfadeStageEvent & {
222
+ reason: string;
223
+ }];
224
+ [PlaybackSessionEvents.stageInvalidated]: [CrossfadeStageEvent];
225
+ [PlaybackSessionEvents.transitionCancelled]: [
226
+ PlaybackEventIdentity<Metadata> & {
227
+ failedGeneration: number;
228
+ entryId: string;
229
+ }
230
+ ];
128
231
  [PlaybackSessionEvents.playbackPaused]: [
129
232
  PlaybackEventIdentity<Metadata> & {
130
233
  /** Playback or transport lifecycle state before this transition. */
package/dist/lifecycle.js CHANGED
@@ -14,6 +14,11 @@ export const PlaybackSessionEvents = {
14
14
  playbackResumed: 'playbackResumed',
15
15
  /** Emitted after seeking to a source timeline position. */
16
16
  playbackSeeked: 'playbackSeeked',
17
+ prepareRequested: 'prepareRequested',
18
+ stageReady: 'stageReady',
19
+ stageFailed: 'stageFailed',
20
+ stageInvalidated: 'stageInvalidated',
21
+ transitionCancelled: 'transitionCancelled',
17
22
  /** Emitted when the configured session filtergraph changes. */
18
23
  filterChanged: 'filterChanged',
19
24
  /** Emitted when the configured session linear gain changes. */
@@ -1,6 +1,6 @@
1
1
  import { RemediaEventEmitter } from './events.js';
2
2
  import { type MediaSource } from './input.js';
3
- import { PlaybackHooks, type PlayOptions, type PlaybackSessionEventMap } from './lifecycle.js';
3
+ import { PlaybackHooks, type PlayOptions, type PlaybackSessionEventMap, type StageNextOptions, type CrossfadeOptions, type StageSnapshot } from './lifecycle.js';
4
4
  import { type AudioStreamInfo, type PlaybackPosition, type PlaybackState } from './types.js';
5
5
  import { FilterControls } from './filters.js';
6
6
  /**
@@ -15,6 +15,24 @@ export declare class PlaybackSession<Metadata = unknown> extends RemediaEventEmi
15
15
  readonly filters: FilterControls;
16
16
  /** Stable opaque identity for this wrapper, suitable for correlating lifecycle events. */
17
17
  get sessionId(): string;
18
+ /** Enable continuous PCM playback before starting a source. */
19
+ /**
20
+ * Configure overlapping PCM playback while idle.
21
+ * @param options - Explicit opt-in settings, or false to retain ordinary playback.
22
+ * @returns Nothing; throws if settings are invalid or playback is active.
23
+ */
24
+ configureCrossfade(options: CrossfadeOptions | false): void;
25
+ /** Current preparation snapshot, or null when no stage is pending. */
26
+ get stagedSource(): StageSnapshot | null;
27
+ /** Cancel the queued stage and release its input. @returns Resolves after cancellation. */
28
+ clearStage(): Promise<void>;
29
+ /**
30
+ * Prepare one upcoming source without restarting playback or its output.
31
+ * @param source - Fresh media input; Readables and buffers require embedded execution.
32
+ * @param options - Queue occurrence, revision fencing, expiry and locally retained metadata.
33
+ * @returns Preparation snapshot; rejects disabled sessions, stale identities or invalid inputs.
34
+ */
35
+ stageNext(source: MediaSource, options: StageNextOptions<Metadata>): Promise<StageSnapshot>;
18
36
  /** Current playback lifecycle state. */
19
37
  get state(): PlaybackState;
20
38
  /** Latest source and output timeline measurements in milliseconds. */
@@ -50,7 +68,9 @@ export declare class PlaybackSession<Metadata = unknown> extends RemediaEventEmi
50
68
  */
51
69
  resume(): Promise<void>;
52
70
  /**
53
- * Seek on the original media timeline; non-seekable and one-shot sources may reject.
71
+ * Seek on the original media timeline. Binary Readable inputs support forward-only
72
+ * seeking by decoding and discarding skipped audio; backwards seeking rejects.
73
+ * Large forward jumps may wait for the producer to supply the skipped bytes.
54
74
  * @param positionMs - Non-negative finite position on the original media timeline, in milliseconds.
55
75
  * @returns Resolves after the backend accepts the seek; rejects for invalid positions or unsupported inputs.
56
76
  */
package/dist/playback.js CHANGED
@@ -26,6 +26,14 @@ export class PlaybackSession extends RemediaEventEmitter {
26
26
  #abortListener;
27
27
  #latestGeneration = 0;
28
28
  #guildId;
29
+ #crossfadeEnabled = false;
30
+ #fadeDurationMs = 5000;
31
+ #crossfadeTimer;
32
+ #stageInput;
33
+ #stageEntryId;
34
+ #stageWork = Promise.resolve();
35
+ #stages = new Map();
36
+ #outgoingInput;
29
37
  /**
30
38
  * Construct this wrapper with its owning services. Use the owning engine or client factory for application code.
31
39
  *
@@ -53,6 +61,123 @@ export class PlaybackSession extends RemediaEventEmitter {
53
61
  get currentGeneration() {
54
62
  return this.#latestGeneration;
55
63
  }
64
+ /** Enable continuous PCM playback before starting a source. */
65
+ /**
66
+ * Configure overlapping PCM playback while idle.
67
+ * @param options - Explicit opt-in settings, or false to retain ordinary playback.
68
+ * @returns Nothing; throws if settings are invalid or playback is active.
69
+ */
70
+ configureCrossfade(options) {
71
+ this.#assertActive();
72
+ if (options) {
73
+ if (options.enabled !== true ||
74
+ (options.curve !== undefined && options.curve !== 'equalPower')) {
75
+ throw new TypeError('crossfade requires enabled: true and the equalPower curve');
76
+ }
77
+ const durationMs = options.durationMs ?? 5000;
78
+ this.#native.playbackConfigureCrossfade(this.#playbackId, true, durationMs, options.prepareBeforeMs ?? 30000);
79
+ this.#fadeDurationMs = durationMs;
80
+ this.#crossfadeEnabled = true;
81
+ }
82
+ else {
83
+ this.#native.playbackConfigureCrossfade(this.#playbackId, false, 0, 0);
84
+ this.#crossfadeEnabled = false;
85
+ }
86
+ }
87
+ /** Current preparation snapshot, or null when no stage is pending. */
88
+ get stagedSource() {
89
+ const stage = this.#native.playbackStagedSource(this.#playbackId);
90
+ return stage ? this.#normalizeStage(stage) : null;
91
+ }
92
+ /** Cancel the queued stage and release its input. @returns Resolves after cancellation. */
93
+ async clearStage() {
94
+ const work = this.#stageWork.then(() => this.#clearStage());
95
+ this.#stageWork = work.then(() => { }, () => { });
96
+ return work;
97
+ }
98
+ async #clearStage() {
99
+ await this.#native.playbackClearStage(this.#playbackId);
100
+ this.#drainCrossfadeEvents();
101
+ await this.#stageInput?.cancel();
102
+ this.#stageInput = undefined;
103
+ this.#stageEntryId = undefined;
104
+ }
105
+ /**
106
+ * Prepare one upcoming source without restarting playback or its output.
107
+ * @param source - Fresh media input; Readables and buffers require embedded execution.
108
+ * @param options - Queue occurrence, revision fencing, expiry and locally retained metadata.
109
+ * @returns Preparation snapshot; rejects disabled sessions, stale identities or invalid inputs.
110
+ */
111
+ async stageNext(source, options) {
112
+ const work = this.#stageWork.then(() => this.#submitStage(source, options));
113
+ this.#stageWork = work.then(() => { }, () => { });
114
+ return work;
115
+ }
116
+ async #submitStage(source, options) {
117
+ this.#assertActive();
118
+ this.#drainCrossfadeEvents();
119
+ if (!this.#crossfadeEnabled)
120
+ throw new Error('crossfade is disabled for this session');
121
+ if (!options.entryId?.trim())
122
+ throw new TypeError('entryId is required');
123
+ if (!Number.isSafeInteger(options.queueRevision) || options.queueRevision < 0) {
124
+ throw new RangeError('queueRevision must be a non-negative safe integer');
125
+ }
126
+ const sourceRevision = options.sourceRevision ?? 0;
127
+ if (!Number.isSafeInteger(sourceRevision) || sourceRevision < 0) {
128
+ throw new RangeError('sourceRevision must be a non-negative safe integer');
129
+ }
130
+ if (options.expiresAtMs !== undefined &&
131
+ (!Number.isSafeInteger(options.expiresAtMs) || options.expiresAtMs < 0)) {
132
+ throw new RangeError('expiresAtMs must be a non-negative safe integer');
133
+ }
134
+ const expectedGeneration = options.expectedGeneration ??
135
+ numericGeneration(this.#native.playbackSourceGeneration(this.#playbackId));
136
+ const existing = this.stagedSource;
137
+ if (existing &&
138
+ existing.expectedGeneration === expectedGeneration &&
139
+ existing.entryId === options.entryId &&
140
+ existing.queueRevision === options.queueRevision &&
141
+ existing.sourceRevision === sourceRevision)
142
+ return existing;
143
+ let input;
144
+ const nativeSource = 'stream' in source
145
+ ? (input = createReadableInput(this.#native, source.stream)).source
146
+ : toNativeSource(source);
147
+ const key = JSON.stringify([
148
+ expectedGeneration,
149
+ options.entryId,
150
+ options.queueRevision,
151
+ sourceRevision,
152
+ ]);
153
+ this.#stages.set(key, { input, metadata: options.customMetadata });
154
+ try {
155
+ const result = await this.#native.playbackStageNext(this.#playbackId, nativeSource, String(expectedGeneration), options.entryId, String(options.queueRevision), String(sourceRevision), options.expiresAtMs === undefined ? undefined : String(options.expiresAtMs));
156
+ this.#drainCrossfadeEvents();
157
+ if (this.#stages.has(key)) {
158
+ this.#stageInput = input;
159
+ this.#stageEntryId = key;
160
+ }
161
+ return this.#normalizeStage(result);
162
+ }
163
+ catch (error) {
164
+ this.#stages.delete(key);
165
+ await input?.cancel();
166
+ throw error;
167
+ }
168
+ }
169
+ #normalizeStage(stage) {
170
+ return {
171
+ expectedGeneration: numericGeneration(stage.expectedGeneration),
172
+ entryId: stage.entryId,
173
+ queueRevision: numericGeneration(stage.queueRevision),
174
+ sourceRevision: numericGeneration(stage.sourceRevision),
175
+ state: stage.state,
176
+ bufferedMs: stage.bufferedMs,
177
+ info: stage.info ? toStreamInfo(stage.info) : null,
178
+ error: stage.error ?? null,
179
+ };
180
+ }
56
181
  /** Current playback lifecycle state. */
57
182
  get state() {
58
183
  return this.#native.playbackState(this.#playbackId);
@@ -153,7 +278,8 @@ export class PlaybackSession extends RemediaEventEmitter {
153
278
  throw abortError(controller.signal.reason);
154
279
  nativeAttempted = true;
155
280
  const info = toStreamInfo(await this.#native.play(this.#playbackId, nativeSource));
156
- const generation = numericGeneration(this.#native.playbackGeneration(this.#playbackId));
281
+ const workerGeneration = numericGeneration(this.#native.playbackGeneration(this.#playbackId));
282
+ const generation = numericGeneration(this.#native.playbackSourceGeneration(this.#playbackId));
157
283
  this.#latestGeneration = generation;
158
284
  this.#metadata.set(generation, options.customMetadata);
159
285
  this.#boundMetadata(generation);
@@ -164,7 +290,9 @@ export class PlaybackSession extends RemediaEventEmitter {
164
290
  info,
165
291
  });
166
292
  this.#starting = false;
167
- void this.#observeGeneration(generation, input);
293
+ if (this.#crossfadeEnabled)
294
+ this.#startCrossfadePoll();
295
+ void this.#observeGeneration(workerGeneration, input);
168
296
  return info;
169
297
  }
170
298
  catch (error) {
@@ -222,7 +350,9 @@ export class PlaybackSession extends RemediaEventEmitter {
222
350
  }
223
351
  }
224
352
  /**
225
- * Seek on the original media timeline; non-seekable and one-shot sources may reject.
353
+ * Seek on the original media timeline. Binary Readable inputs support forward-only
354
+ * seeking by decoding and discarding skipped audio; backwards seeking rejects.
355
+ * Large forward jumps may wait for the producer to supply the skipped bytes.
226
356
  * @param positionMs - Non-negative finite position on the original media timeline, in milliseconds.
227
357
  * @returns Resolves after the backend accepts the seek; rejects for invalid positions or unsupported inputs.
228
358
  */
@@ -230,7 +360,8 @@ export class PlaybackSession extends RemediaEventEmitter {
230
360
  this.#assertActive();
231
361
  const previousPositionMs = this.position.mediaMs;
232
362
  await this.#native.seek(this.#playbackId, positionMs);
233
- if (previousPositionMs !== positionMs) {
363
+ this.#drainCrossfadeEvents();
364
+ if (previousPositionMs !== positionMs || this.#crossfadeEnabled) {
234
365
  this.emit(PlaybackEvent.playbackSeeked, {
235
366
  ...this.#eventContext(),
236
367
  positionMs,
@@ -245,7 +376,7 @@ export class PlaybackSession extends RemediaEventEmitter {
245
376
  async stop() {
246
377
  this.#assertActive();
247
378
  const previousState = this.state;
248
- const generation = numericGeneration(this.#native.playbackGeneration(this.#playbackId));
379
+ const generation = this.#latestGeneration;
249
380
  try {
250
381
  await this.#native.stop(this.#playbackId);
251
382
  if (isPlaybackActive(previousState) && this.state === 'stopped') {
@@ -287,6 +418,9 @@ export class PlaybackSession extends RemediaEventEmitter {
287
418
  finally {
288
419
  await this.#releaseInput();
289
420
  this.#disposed = true;
421
+ this.#stopCrossfadePoll();
422
+ await this.#stageInput?.cancel();
423
+ await this.#outgoingInput?.cancel();
290
424
  this.hooks.clear();
291
425
  this.#metadata.clear();
292
426
  this.emit(PlaybackEvent.sessionDisposed, {
@@ -331,8 +465,9 @@ export class PlaybackSession extends RemediaEventEmitter {
331
465
  try {
332
466
  const state = (await this.#native.wait(this.#playbackId, String(generation)));
333
467
  if (state === 'completed' || state === 'failed' || state === 'stopped') {
468
+ this.#drainCrossfadeEvents();
334
469
  const error = state === 'failed' ? new Error(this.error ?? 'playback failed') : undefined;
335
- this.#emitTerminal(state, generation, error);
470
+ this.#emitTerminal(state, this.#latestGeneration, error);
336
471
  }
337
472
  }
338
473
  catch (error) {
@@ -349,19 +484,168 @@ export class PlaybackSession extends RemediaEventEmitter {
349
484
  state = undefined;
350
485
  }
351
486
  if (state === 'failed')
352
- this.#emitTerminal('failed', generation, asError(error));
487
+ this.#emitTerminal('failed', this.#latestGeneration, asError(error));
353
488
  }
354
489
  }
355
490
  finally {
356
- this.#metadata.delete(generation);
357
- this.#startedGenerations.delete(generation);
358
- if (this.#latestGeneration === generation) {
359
- this.#clearAbortBinding(this.#playController);
491
+ this.#stopCrossfadePoll();
492
+ this.#clearAbortBinding(this.#playController);
493
+ await this.#outgoingInput?.cancel();
494
+ this.#outgoingInput = undefined;
495
+ await this.#stageInput?.cancel();
496
+ this.#stageInput = undefined;
497
+ for (const stage of this.#stages.values())
498
+ await stage.input?.cancel();
499
+ this.#stages.clear();
500
+ await this.#releaseInput();
501
+ if (input !== this.#input)
502
+ await input?.cancel();
503
+ }
504
+ }
505
+ #startCrossfadePoll() {
506
+ if (this.#crossfadeTimer)
507
+ return;
508
+ this.#crossfadeTimer = setInterval(() => this.#drainCrossfadeEvents(), 25);
509
+ this.#crossfadeTimer.unref?.();
510
+ }
511
+ #stopCrossfadePoll() {
512
+ if (this.#crossfadeTimer)
513
+ clearInterval(this.#crossfadeTimer);
514
+ this.#crossfadeTimer = undefined;
515
+ }
516
+ #drainCrossfadeEvents() {
517
+ if (!this.#crossfadeEnabled || this.#disposed)
518
+ return;
519
+ let events;
520
+ try {
521
+ events = this.#native.playbackTakeCrossfadeEvents(this.#playbackId);
522
+ }
523
+ catch {
524
+ return;
525
+ }
526
+ for (const event of events) {
527
+ const generation = numericGeneration(event.generation);
528
+ const stage = event.entryId === undefined
529
+ ? null
530
+ : {
531
+ entryId: event.entryId,
532
+ queueRevision: numericGeneration(event.queueRevision ?? '0'),
533
+ sourceRevision: numericGeneration(event.sourceRevision ?? '0'),
534
+ };
535
+ const stageKey = JSON.stringify([
536
+ event.kind === 'transition_started'
537
+ ? numericGeneration(event.previousGeneration ?? '0')
538
+ : generation,
539
+ stage?.entryId,
540
+ stage?.queueRevision,
541
+ stage?.sourceRevision,
542
+ ]);
543
+ switch (event.kind) {
544
+ case 'timeline_changed': {
545
+ const previous = numericGeneration(event.previousGeneration ?? '0');
546
+ this.#metadata.set(generation, this.#metadata.get(previous));
547
+ this.#startedGenerations.add(generation);
548
+ this.#latestGeneration = generation;
549
+ break;
550
+ }
551
+ case 'prepare_requested': {
552
+ const remainingMs = event.remainingMs ?? 0;
553
+ this.emit(PlaybackEvent.prepareRequested, {
554
+ ...this.#eventContext(generation),
555
+ remainingMs,
556
+ transitionInMs: Math.max(0, remainingMs - this.#fadeDurationMs),
557
+ });
558
+ break;
559
+ }
560
+ case 'stage_ready':
561
+ if (stage)
562
+ this.emit(PlaybackEvent.stageReady, {
563
+ ...this.#eventContext(generation),
564
+ ...stage,
565
+ });
566
+ break;
567
+ case 'stage_failed':
568
+ void this.#stages.get(stageKey)?.input?.cancel();
569
+ this.#stages.delete(stageKey);
570
+ if (stage)
571
+ this.emit(PlaybackEvent.stageFailed, {
572
+ ...this.#eventContext(generation),
573
+ ...stage,
574
+ reason: event.reason ?? 'staged source failed',
575
+ });
576
+ break;
577
+ case 'stage_invalidated':
578
+ void this.#stages.get(stageKey)?.input?.cancel();
579
+ this.#stages.delete(stageKey);
580
+ if (stage) {
581
+ this.emit(PlaybackEvent.stageInvalidated, {
582
+ ...this.#eventContext(generation),
583
+ ...stage,
584
+ });
585
+ if (this.#stageEntryId === stageKey) {
586
+ void this.#stageInput?.cancel();
587
+ this.#stageInput = undefined;
588
+ this.#stageEntryId = undefined;
589
+ }
590
+ }
591
+ break;
592
+ case 'transition_started': {
593
+ if (!stage || !event.info)
594
+ break;
595
+ const previous = numericGeneration(event.previousGeneration ?? '0');
596
+ const prepared = this.#stages.get(stageKey);
597
+ this.#stages.delete(stageKey);
598
+ this.#metadata.set(generation, prepared?.metadata);
599
+ this.#boundMetadata(generation);
600
+ this.#startedGenerations.add(generation);
601
+ this.#latestGeneration = generation;
602
+ this.#outgoingInput = this.#input;
603
+ this.#input = prepared?.input;
604
+ if (this.#stageEntryId === stageKey) {
605
+ this.#stageInput = undefined;
606
+ this.#stageEntryId = undefined;
607
+ }
608
+ this.emit(PlaybackEvent.playbackStarted, {
609
+ ...this.#eventContext(generation),
610
+ state: 'playing',
611
+ info: toStreamInfo(event.info),
612
+ transition: { type: 'crossfade', outgoingGeneration: previous, entryId: stage.entryId },
613
+ });
614
+ break;
615
+ }
616
+ case 'transition_completed': {
617
+ if (!stage)
618
+ break;
619
+ const promoted = numericGeneration(event.previousGeneration ?? '0');
620
+ this.#emitTerminal('completed', generation, undefined, undefined, {
621
+ type: 'promoted',
622
+ generation: promoted,
623
+ entryId: stage.entryId,
624
+ });
625
+ void this.#outgoingInput?.cancel();
626
+ this.#outgoingInput = undefined;
627
+ break;
628
+ }
629
+ case 'transition_cancelled': {
630
+ if (!stage)
631
+ break;
632
+ const failedGeneration = numericGeneration(event.previousGeneration ?? '0');
633
+ const abandoned = this.#input;
634
+ this.#input = this.#outgoingInput;
635
+ this.#outgoingInput = undefined;
636
+ void abandoned?.cancel();
637
+ this.#latestGeneration = generation;
638
+ this.emit(PlaybackEvent.transitionCancelled, {
639
+ ...this.#eventContext(generation),
640
+ failedGeneration,
641
+ entryId: stage.entryId,
642
+ });
643
+ break;
644
+ }
360
645
  }
361
- await this.#releaseInput(input, generation);
362
646
  }
363
647
  }
364
- #emitTerminal(state, generation, error, reason) {
648
+ #emitTerminal(state, generation, error, reason, continuation) {
365
649
  if ((state !== 'failed' && !this.#startedGenerations.has(generation)) ||
366
650
  this.#terminalGenerations.has(generation))
367
651
  return;
@@ -374,7 +658,12 @@ export class PlaybackSession extends RemediaEventEmitter {
374
658
  }
375
659
  const base = this.#eventContext(generation);
376
660
  if (state === 'completed') {
377
- this.emit(PlaybackEvent.playbackCompleted, { ...base, state, position: this.position });
661
+ this.emit(PlaybackEvent.playbackCompleted, {
662
+ ...base,
663
+ state,
664
+ position: this.position,
665
+ ...(continuation ? { continuation } : {}),
666
+ });
378
667
  }
379
668
  else if (state === 'stopped') {
380
669
  this.emit(PlaybackEvent.playbackStopped, reason ? { ...base, state, reason } : { ...base, state });
package/dist/remedia.js CHANGED
@@ -172,6 +172,11 @@ function forwardLifecycleEvents(source, target) {
172
172
  PlaybackEvent.playbackPaused,
173
173
  PlaybackEvent.playbackResumed,
174
174
  PlaybackEvent.playbackSeeked,
175
+ PlaybackEvent.prepareRequested,
176
+ PlaybackEvent.stageReady,
177
+ PlaybackEvent.stageFailed,
178
+ PlaybackEvent.stageInvalidated,
179
+ PlaybackEvent.transitionCancelled,
175
180
  PlaybackEvent.filterChanged,
176
181
  PlaybackEvent.volumeChanged,
177
182
  PlaybackEvent.sessionDisposed,
package/native.d.ts CHANGED
@@ -68,6 +68,22 @@ export declare class NativeRemedia {
68
68
  createPlaybackSession(): string
69
69
  /** Start decoding into the null output or the associated Discord Opus sender. */
70
70
  play(playbackId: string, source: NativeMediaSource): Promise<NativeStreamInfo>
71
+ /** Configure the optional continuous PCM transition worker before playback. */
72
+ playbackConfigureCrossfade(playbackId: string, enabled: boolean, durationMs: number, prepareBeforeMs: number): void
73
+ /**
74
+ * Open an independent decoder and stage a queue occurrence without
75
+ * interrupting current playback.
76
+ */
77
+ playbackStageNext(playbackId: string, source: NativeMediaSource, expectedGeneration: string, entryId: string, queueRevision: string, sourceRevision: string, expiresAtMs?: string | undefined | null): Promise<NativeStageSnapshot>
78
+ /** Return the current stage without opening a new decoder. */
79
+ playbackStagedSource(playbackId: string): NativeStageSnapshot | null
80
+ playbackClearStage(playbackId: string): Promise<void>
81
+ /**
82
+ * Drain native transition events; embedded wrappers forward these to JS
83
+ * using the same event names and generation semantics as remote mode.
84
+ */
85
+ playbackTakeCrossfadeEvents(playbackId: string): Array<NativeCrossfadeEvent>
86
+ playbackSourceGeneration(playbackId: string): string
71
87
  /** Request playback pause at the current output frame boundary. */
72
88
  pause(playbackId: string): Promise<void>
73
89
  /** Resume a paused playback session. */
@@ -122,6 +138,19 @@ export declare class NativeRemedia {
122
138
  probe(id: string, source: NativeMediaSource, timeoutMs: number): Promise<NativeStreamInfo>
123
139
  }
124
140
 
141
+ /** One ordered event emitted by the native staged-source worker. */
142
+ export interface NativeCrossfadeEvent {
143
+ kind: string
144
+ generation: string
145
+ previousGeneration?: string
146
+ entryId?: string
147
+ queueRevision?: string
148
+ sourceRevision?: string
149
+ remainingMs?: number
150
+ reason?: string
151
+ info?: NativeStreamInfo
152
+ }
153
+
125
154
  export interface NativeDiagnosticEvent {
126
155
  timestamp: number
127
156
  severity: string
@@ -154,6 +183,18 @@ export interface NativePlaybackPosition {
154
183
  playedMs?: number
155
184
  }
156
185
 
186
+ /** A bounded native stage with an application-owned queue occurrence identity. */
187
+ export interface NativeStageSnapshot {
188
+ expectedGeneration: string
189
+ entryId: string
190
+ queueRevision: string
191
+ sourceRevision: string
192
+ state: string
193
+ bufferedMs: number
194
+ info?: NativeStreamInfo
195
+ error?: string
196
+ }
197
+
157
198
  export interface NativeStreamInfo {
158
199
  streamIndex: number
159
200
  codec: string
package/native.js CHANGED
@@ -97,8 +97,8 @@ function requireNative() {
97
97
  try {
98
98
  const binding = require('@remedia/node-android-arm64')
99
99
  const bindingPackageVersion = require('@remedia/node-android-arm64/package.json').version
100
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
101
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
100
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
101
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
102
102
  }
103
103
  return binding
104
104
  } catch (e) {
@@ -113,8 +113,8 @@ function requireNative() {
113
113
  try {
114
114
  const binding = require('@remedia/node-android-arm-eabi')
115
115
  const bindingPackageVersion = require('@remedia/node-android-arm-eabi/package.json').version
116
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
117
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
116
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
117
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
118
118
  }
119
119
  return binding
120
120
  } catch (e) {
@@ -134,8 +134,8 @@ function requireNative() {
134
134
  try {
135
135
  const binding = require('@remedia/node-win32-x64-gnu')
136
136
  const bindingPackageVersion = require('@remedia/node-win32-x64-gnu/package.json').version
137
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
138
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
137
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
138
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
139
139
  }
140
140
  return binding
141
141
  } catch (e) {
@@ -150,8 +150,8 @@ function requireNative() {
150
150
  try {
151
151
  const binding = require('@remedia/node-win32-x64-msvc')
152
152
  const bindingPackageVersion = require('@remedia/node-win32-x64-msvc/package.json').version
153
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
154
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
153
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
154
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
155
155
  }
156
156
  return binding
157
157
  } catch (e) {
@@ -167,8 +167,8 @@ function requireNative() {
167
167
  try {
168
168
  const binding = require('@remedia/node-win32-ia32-msvc')
169
169
  const bindingPackageVersion = require('@remedia/node-win32-ia32-msvc/package.json').version
170
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
171
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
170
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
171
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
172
172
  }
173
173
  return binding
174
174
  } catch (e) {
@@ -183,8 +183,8 @@ function requireNative() {
183
183
  try {
184
184
  const binding = require('@remedia/node-win32-arm64-msvc')
185
185
  const bindingPackageVersion = require('@remedia/node-win32-arm64-msvc/package.json').version
186
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
187
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
186
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
187
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
188
188
  }
189
189
  return binding
190
190
  } catch (e) {
@@ -202,8 +202,8 @@ function requireNative() {
202
202
  try {
203
203
  const binding = require('@remedia/node-darwin-universal')
204
204
  const bindingPackageVersion = require('@remedia/node-darwin-universal/package.json').version
205
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
206
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
205
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
206
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
207
207
  }
208
208
  return binding
209
209
  } catch (e) {
@@ -218,8 +218,8 @@ function requireNative() {
218
218
  try {
219
219
  const binding = require('@remedia/node-darwin-x64')
220
220
  const bindingPackageVersion = require('@remedia/node-darwin-x64/package.json').version
221
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
222
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
221
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
222
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
223
223
  }
224
224
  return binding
225
225
  } catch (e) {
@@ -234,8 +234,8 @@ function requireNative() {
234
234
  try {
235
235
  const binding = require('@remedia/node-darwin-arm64')
236
236
  const bindingPackageVersion = require('@remedia/node-darwin-arm64/package.json').version
237
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
238
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
237
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
238
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
239
239
  }
240
240
  return binding
241
241
  } catch (e) {
@@ -254,8 +254,8 @@ function requireNative() {
254
254
  try {
255
255
  const binding = require('@remedia/node-freebsd-x64')
256
256
  const bindingPackageVersion = require('@remedia/node-freebsd-x64/package.json').version
257
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
258
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
257
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
258
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
259
259
  }
260
260
  return binding
261
261
  } catch (e) {
@@ -270,8 +270,8 @@ function requireNative() {
270
270
  try {
271
271
  const binding = require('@remedia/node-freebsd-arm64')
272
272
  const bindingPackageVersion = require('@remedia/node-freebsd-arm64/package.json').version
273
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
274
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
273
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
274
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
275
275
  }
276
276
  return binding
277
277
  } catch (e) {
@@ -286,8 +286,8 @@ function requireNative() {
286
286
  try {
287
287
  const binding = require('@remedia/node-freebsd-ppc64')
288
288
  const bindingPackageVersion = require('@remedia/node-freebsd-ppc64/package.json').version
289
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
290
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
289
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
290
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
291
291
  }
292
292
  return binding
293
293
  } catch (e) {
@@ -307,8 +307,8 @@ function requireNative() {
307
307
  try {
308
308
  const binding = require('@remedia/node-linux-x64-musl')
309
309
  const bindingPackageVersion = require('@remedia/node-linux-x64-musl/package.json').version
310
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
311
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
310
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
311
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
312
312
  }
313
313
  return binding
314
314
  } catch (e) {
@@ -323,8 +323,8 @@ function requireNative() {
323
323
  try {
324
324
  const binding = require('@remedia/node-linux-x64-gnu')
325
325
  const bindingPackageVersion = require('@remedia/node-linux-x64-gnu/package.json').version
326
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
327
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
326
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
327
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
328
328
  }
329
329
  return binding
330
330
  } catch (e) {
@@ -341,8 +341,8 @@ function requireNative() {
341
341
  try {
342
342
  const binding = require('@remedia/node-linux-arm64-musl')
343
343
  const bindingPackageVersion = require('@remedia/node-linux-arm64-musl/package.json').version
344
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
345
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
344
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
345
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
346
346
  }
347
347
  return binding
348
348
  } catch (e) {
@@ -357,8 +357,8 @@ function requireNative() {
357
357
  try {
358
358
  const binding = require('@remedia/node-linux-arm64-gnu')
359
359
  const bindingPackageVersion = require('@remedia/node-linux-arm64-gnu/package.json').version
360
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
361
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
360
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
361
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
362
362
  }
363
363
  return binding
364
364
  } catch (e) {
@@ -375,8 +375,8 @@ function requireNative() {
375
375
  try {
376
376
  const binding = require('@remedia/node-linux-arm-musleabihf')
377
377
  const bindingPackageVersion = require('@remedia/node-linux-arm-musleabihf/package.json').version
378
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
379
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
378
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
379
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
380
380
  }
381
381
  return binding
382
382
  } catch (e) {
@@ -391,8 +391,8 @@ function requireNative() {
391
391
  try {
392
392
  const binding = require('@remedia/node-linux-arm-gnueabihf')
393
393
  const bindingPackageVersion = require('@remedia/node-linux-arm-gnueabihf/package.json').version
394
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
395
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
394
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
395
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
396
396
  }
397
397
  return binding
398
398
  } catch (e) {
@@ -409,8 +409,8 @@ function requireNative() {
409
409
  try {
410
410
  const binding = require('@remedia/node-linux-loong64-musl')
411
411
  const bindingPackageVersion = require('@remedia/node-linux-loong64-musl/package.json').version
412
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
413
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
412
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
413
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
414
414
  }
415
415
  return binding
416
416
  } catch (e) {
@@ -425,8 +425,8 @@ function requireNative() {
425
425
  try {
426
426
  const binding = require('@remedia/node-linux-loong64-gnu')
427
427
  const bindingPackageVersion = require('@remedia/node-linux-loong64-gnu/package.json').version
428
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
429
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
428
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
429
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
430
430
  }
431
431
  return binding
432
432
  } catch (e) {
@@ -443,8 +443,8 @@ function requireNative() {
443
443
  try {
444
444
  const binding = require('@remedia/node-linux-riscv64-musl')
445
445
  const bindingPackageVersion = require('@remedia/node-linux-riscv64-musl/package.json').version
446
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
447
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
446
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
447
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
448
448
  }
449
449
  return binding
450
450
  } catch (e) {
@@ -459,8 +459,8 @@ function requireNative() {
459
459
  try {
460
460
  const binding = require('@remedia/node-linux-riscv64-gnu')
461
461
  const bindingPackageVersion = require('@remedia/node-linux-riscv64-gnu/package.json').version
462
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
463
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
462
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
463
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
464
464
  }
465
465
  return binding
466
466
  } catch (e) {
@@ -476,8 +476,8 @@ function requireNative() {
476
476
  try {
477
477
  const binding = require('@remedia/node-linux-ppc64-gnu')
478
478
  const bindingPackageVersion = require('@remedia/node-linux-ppc64-gnu/package.json').version
479
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
480
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
479
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
480
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
481
481
  }
482
482
  return binding
483
483
  } catch (e) {
@@ -492,8 +492,8 @@ function requireNative() {
492
492
  try {
493
493
  const binding = require('@remedia/node-linux-s390x-gnu')
494
494
  const bindingPackageVersion = require('@remedia/node-linux-s390x-gnu/package.json').version
495
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
496
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
495
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
496
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
497
497
  }
498
498
  return binding
499
499
  } catch (e) {
@@ -512,8 +512,8 @@ function requireNative() {
512
512
  try {
513
513
  const binding = require('@remedia/node-openharmony-arm64')
514
514
  const bindingPackageVersion = require('@remedia/node-openharmony-arm64/package.json').version
515
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
516
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
515
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
516
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
517
517
  }
518
518
  return binding
519
519
  } catch (e) {
@@ -528,8 +528,8 @@ function requireNative() {
528
528
  try {
529
529
  const binding = require('@remedia/node-openharmony-x64')
530
530
  const bindingPackageVersion = require('@remedia/node-openharmony-x64/package.json').version
531
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
532
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
531
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
532
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
533
533
  }
534
534
  return binding
535
535
  } catch (e) {
@@ -544,8 +544,8 @@ function requireNative() {
544
544
  try {
545
545
  const binding = require('@remedia/node-openharmony-arm')
546
546
  const bindingPackageVersion = require('@remedia/node-openharmony-arm/package.json').version
547
- if (bindingPackageVersion !== '0.1.0-dev.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
548
- throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
547
+ if (bindingPackageVersion !== '0.1.0-dev.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
548
+ throw new Error(`Native binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
549
549
  }
550
550
  return binding
551
551
  } catch (e) {
@@ -686,8 +686,8 @@ if (!nativeBinding || forceWasi) {
686
686
  if (!candidateFailed) {
687
687
  if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
688
688
  const bindingPackageVersion = require('@remedia/node-wasm32-wasi/package.json').version
689
- if (bindingPackageVersion !== '0.1.0-dev.2') {
690
- throw new Error(`WASI binding package version mismatch, expected 0.1.0-dev.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
689
+ if (bindingPackageVersion !== '0.1.0-dev.4') {
690
+ throw new Error(`WASI binding package version mismatch, expected 0.1.0-dev.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
691
691
  }
692
692
  }
693
693
  wasiBinding = require('@remedia/node-wasm32-wasi')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remedia/node",
3
- "version": "0.1.0-dev.2",
3
+ "version": "0.1.0-dev.4",
4
4
  "description": "Native Node.js playback and Discord voice bindings for Remedia",
5
5
  "license": "MIT",
6
6
  "author": "Twilight <hello@twlite.dev>",
@@ -61,19 +61,19 @@
61
61
  },
62
62
  "private": false,
63
63
  "optionalDependencies": {
64
- "@remedia/node-linux-x64-gnu": "0.1.0-dev.2",
65
- "@remedia/node-linux-arm64-gnu": "0.1.0-dev.2",
66
- "@remedia/node-darwin-x64": "0.1.0-dev.2",
67
- "@remedia/node-darwin-arm64": "0.1.0-dev.2",
68
- "@remedia/node-win32-x64-msvc": "0.1.0-dev.2",
69
- "@remedia/node-linux-x64-musl": "0.1.0-dev.2",
70
- "@remedia/node-linux-arm64-musl": "0.1.0-dev.2",
71
- "@remedia/node-linux-arm-gnueabihf": "0.1.0-dev.2",
72
- "@remedia/node-win32-ia32-msvc": "0.1.0-dev.2",
73
- "@remedia/node-win32-arm64-msvc": "0.1.0-dev.2",
74
- "@remedia/node-android-arm64": "0.1.0-dev.2",
75
- "@remedia/node-android-arm-eabi": "0.1.0-dev.2",
76
- "@remedia/node-freebsd-x64": "0.1.0-dev.2"
64
+ "@remedia/node-linux-x64-gnu": "0.1.0-dev.4",
65
+ "@remedia/node-linux-arm64-gnu": "0.1.0-dev.4",
66
+ "@remedia/node-darwin-x64": "0.1.0-dev.4",
67
+ "@remedia/node-darwin-arm64": "0.1.0-dev.4",
68
+ "@remedia/node-win32-x64-msvc": "0.1.0-dev.4",
69
+ "@remedia/node-linux-x64-musl": "0.1.0-dev.4",
70
+ "@remedia/node-linux-arm64-musl": "0.1.0-dev.4",
71
+ "@remedia/node-linux-arm-gnueabihf": "0.1.0-dev.4",
72
+ "@remedia/node-win32-ia32-msvc": "0.1.0-dev.4",
73
+ "@remedia/node-win32-arm64-msvc": "0.1.0-dev.4",
74
+ "@remedia/node-android-arm64": "0.1.0-dev.4",
75
+ "@remedia/node-android-arm-eabi": "0.1.0-dev.4",
76
+ "@remedia/node-freebsd-x64": "0.1.0-dev.4"
77
77
  },
78
78
  "scripts": {
79
79
  "build": "pnpm run build:native && pnpm run build:types",