modern-cmdk 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,6 @@
1
1
  import { API, FileInfo } from "jscodeshift";
2
- //#region src/codemod/transforms/data-attrs.d.ts
3
2
  /**
4
3
  * jscodeshift transform — renames cmdk data attributes in JSX and
5
4
  * CSS selectors within string/template literals.
6
5
  */
7
- export default function transform(fileInfo: FileInfo, api: API): string;
8
- //#endregion
6
+ export default function transform(fileInfo: FileInfo, api: API): string;
@@ -1,4 +1,4 @@
1
- //#region src/codemod/transforms/data-attrs.ts
1
+ // src/codemod/transforms/data-attrs.ts
2
2
  /** Mapping from old bare attribute names to new data-attribute names */
3
3
  const ATTR_MAP = /* @__PURE__ */ new Map([
4
4
  ["cmdk-root", "data-command"],
@@ -14,7 +14,7 @@ const ATTR_MAP = /* @__PURE__ */ new Map([
14
14
  const CSS_VAR_MAP = /* @__PURE__ */ new Map([["--cmdk-list-height", "--command-list-height"]]);
15
15
  /**
16
16
  * Replace all cmdk attribute selectors (bracketed) and CSS vars in a string.
17
- * Uses ES2026 Set.union to combine both maps into a single pass.
17
+ * Runs replaceAll for each ATTR_MAP entry (bracketed selectors), then for each CSS_VAR_MAP entry.
18
18
  */
19
19
  function replaceInString(input) {
20
20
  let result = input;
@@ -62,5 +62,4 @@ function transform(fileInfo, api) {
62
62
  });
63
63
  return hasChanges ? root.toSource() : fileInfo.source;
64
64
  }
65
- //#endregion
66
65
  export { transform as default };
@@ -1,8 +1,6 @@
1
1
  import { API, FileInfo } from "jscodeshift";
2
- //#region src/codemod/transforms/forward-ref.d.ts
3
2
  /**
4
3
  * jscodeshift transform — removes forwardRef wrappers and merges the
5
4
  * ref parameter into the props object as a regular prop.
6
5
  */
7
- export default function transform(fileInfo: FileInfo, api: API): string;
8
- //#endregion
6
+ export default function transform(fileInfo: FileInfo, api: API): string;
@@ -1,4 +1,4 @@
1
- //#region src/codemod/transforms/forward-ref.ts
1
+ // src/codemod/transforms/forward-ref.ts
2
2
  /**
3
3
  * jscodeshift transform — removes forwardRef wrappers and merges the
4
4
  * ref parameter into the props object as a regular prop.
@@ -47,5 +47,4 @@ function transform(fileInfo, api) {
47
47
  }
48
48
  return hasChanges ? root.toSource() : fileInfo.source;
49
49
  }
50
- //#endregion
51
50
  export { transform as default };
@@ -1,8 +1,6 @@
1
1
  import { API, FileInfo } from "jscodeshift";
2
- //#region src/codemod/transforms/import-rewrite.d.ts
3
2
  /**
4
3
  * jscodeshift transform — rewrites all import/require/re-export paths
5
4
  * from `cmdk` to `modern-cmdk/react`.
6
5
  */
7
- export default function transform(fileInfo: FileInfo, api: API): string;
8
- //#endregion
6
+ export default function transform(fileInfo: FileInfo, api: API): string;
@@ -1,4 +1,4 @@
1
- //#region src/codemod/transforms/import-rewrite.ts
1
+ // src/codemod/transforms/import-rewrite.ts
2
2
  const OLD_PACKAGE = "cmdk";
3
3
  const NEW_PACKAGE = "modern-cmdk/react";
4
4
  /**
@@ -39,5 +39,4 @@ function transform(fileInfo, api) {
39
39
  });
40
40
  return hasChanges ? root.toSource() : fileInfo.source;
41
41
  }
42
- //#endregion
43
42
  export { transform as default };
@@ -1,7 +1,5 @@
1
1
  import { API, FileInfo } from "jscodeshift";
2
- //#region src/codemod/transforms/should-filter.d.ts
3
2
  /**
4
3
  * jscodeshift transform — migrates shouldFilter prop to filter.
5
4
  */
6
- export default function transform(fileInfo: FileInfo, api: API): string;
7
- //#endregion
5
+ export default function transform(fileInfo: FileInfo, api: API): string;
@@ -1,4 +1,4 @@
1
- //#region src/codemod/transforms/should-filter.ts
1
+ // src/codemod/transforms/should-filter.ts
2
2
  /**
3
3
  * jscodeshift transform — migrates shouldFilter prop to filter.
4
4
  */
@@ -15,5 +15,4 @@ function transform(fileInfo, api) {
15
15
  });
16
16
  return hasChanges ? root.toSource() : fileInfo.source;
17
17
  }
18
- //#endregion
19
18
  export { transform as default };
@@ -1,9 +1,8 @@
1
- //#region src/core/search/types.d.ts
2
1
  /** Result of scoring a single item against a query */
3
2
  interface SearchResult {
4
3
  readonly id: ItemId;
5
4
  readonly score: number;
6
- /** Character ranges that matched (for highlighting) — [start, end] tuples */
5
+ /** Character ranges that matched (for highlighting) — half-open [start, end) tuples, end exclusive */
7
6
  readonly matches: ReadonlyArray<readonly [start: number, end: number]>;
8
7
  }
9
8
  /** A scoring function that evaluates a single item against a query */
@@ -14,15 +13,13 @@ interface SearchEngine extends Disposable {
14
13
  index(items: readonly CommandItem[]): void;
15
14
  /** Search items by query, return ordered results — uses Iterator pipeline */
16
15
  search(query: string, items: readonly CommandItem[]): IteratorObject<SearchResult>;
17
- /** Remove items from index — uses Set.difference for efficient bulk removal */
16
+ /** Remove items from index by id */
18
17
  remove(ids: ReadonlySet<ItemId>): void;
19
18
  /** Clear the entire index */
20
19
  clear(): void;
21
20
  /** Dispose resources */
22
21
  [Symbol.dispose](): void;
23
22
  }
24
- //#endregion
25
- //#region src/core/types.d.ts
26
23
  /**
27
24
  * Branded type for command item IDs.
28
25
  * Prevents accidental mixing with plain strings at the type level.
@@ -165,7 +162,7 @@ interface FrecencyStorage extends Disposable {
165
162
  load(namespace: string): FrecencyData | Promise<FrecencyData>;
166
163
  save(namespace: string, data: FrecencyData): void | Promise<void>;
167
164
  }
168
- /** Frecency exponential decay bucket configuration */
165
+ /** Frecency step-weight configuration per recency bucket (hour/day/week/month/older) */
169
166
  interface FrecencyDecayConfig {
170
167
  readonly hourWeight?: number | undefined;
171
168
  readonly dayWeight?: number | undefined;
@@ -182,7 +179,7 @@ interface FrecencyOptions {
182
179
  }
183
180
  /** Default frecency decay configuration */
184
181
  export declare const DEFAULT_FRECENCY_DECAY: Required<FrecencyDecayConfig>;
185
- /** Options for creating a command machine — const type param for narrowed option inference */
182
+ /** Options for creating a command machine */
186
183
  interface CommandMachineOptions {
187
184
  /** Pre-registered items to populate on creation */
188
185
  readonly items?: readonly CommandItem[] | undefined;
@@ -208,17 +205,15 @@ interface CommandMachineOptions {
208
205
  readonly onSearchChange?: ((query: string) => void) | undefined;
209
206
  /** Whether keyboard navigation loops from last to first item (default: true) */
210
207
  readonly loop?: boolean | undefined;
211
- /** Item count threshold for automatic virtualization (default: 100) */
208
+ /** Accepted but not read yet: Command.List uses fixed thresholds (on above 100 matches, off at 50 or fewer) (default: 100) */
212
209
  readonly virtualizeThreshold?: number | undefined;
213
210
  }
214
211
  /** Default machine options */
215
212
  export declare const DEFAULT_MACHINE_OPTIONS: Partial<CommandMachineOptions>;
216
213
  /** Initial state factory */
217
214
  export declare function createInitialState(options?: CommandMachineOptions): CommandState;
218
- //#endregion
219
- //#region src/core/frecency/idb-storage.d.ts
220
215
  /**
221
- * IndexedDB-backed frecency storage using idb-keyval 6.2.2.
216
+ * IndexedDB-backed frecency storage using idb-keyval.
222
217
  *
223
218
  * Persists frecency data across browser sessions. Implements both
224
219
  * `Disposable` and `AsyncDisposable` for use with `using` and `await using`.
@@ -252,12 +247,10 @@ export declare class IdbFrecencyStorage implements FrecencyStorage, AsyncDisposa
252
247
  /** Async dispose — marks as disposed, suitable for `await using` */
253
248
  [Symbol.asyncDispose](): Promise<void>;
254
249
  }
255
- //#endregion
256
- //#region src/core/frecency/index.d.ts
257
250
  /**
258
251
  * Computes a frecency bonus for an item based on usage frequency and recency.
259
252
  * Uses hour/day/week/month bucket boundaries with
260
- * configurable exponential decay weights per time bucket.
253
+ * configurable step weights per recency bucket (hour/day/week/month/older).
261
254
  */
262
255
  export declare function computeFrecencyBonus(history: FrecencyRecord, now?: number, config?: FrecencyDecayConfig): number;
263
256
  /**
@@ -288,8 +281,6 @@ export declare class FrecencyEngine implements Disposable, AsyncDisposable {
288
281
  [Symbol.asyncDispose](): Promise<void>;
289
282
  [Symbol.dispose](): void;
290
283
  }
291
- //#endregion
292
- //#region src/core/frecency/memory-storage.d.ts
293
284
  /**
294
285
  * In-memory implementation of FrecencyStorage using a Map.
295
286
  * Data does not persist across page reloads. Suitable for ephemeral
@@ -299,14 +290,12 @@ export declare class MemoryFrecencyStorage implements FrecencyStorage {
299
290
  #private;
300
291
  load(namespace: string): FrecencyData;
301
292
  save(namespace: string, data: FrecencyData): void;
302
- /** Serialize all stored data — Iterator Helpers pipeline (ES2026) */
293
+ /** Serialize all stored data — Iterator Helpers pipeline (ES2025) */
303
294
  toJSON(): Record<string, {
304
295
  records: Array<[string, FrecencyRecord]>;
305
296
  }>;
306
297
  [Symbol.dispose](): void;
307
298
  }
308
- //#endregion
309
- //#region src/core/keyboard/parser.d.ts
310
299
  /**
311
300
  * Structured representation of a keyboard shortcut after parsing.
312
301
  * The `normalized` field provides a deterministic string for dedup and comparison.
@@ -330,8 +319,6 @@ export declare function parseShortcut(shortcut: string): ParsedShortcut;
330
319
  * On macOS: renders glyphs (⌘, ⇧, ⌥, ⌃). On other platforms: text labels joined by "+".
331
320
  */
332
321
  export declare function formatShortcut(parsed: ParsedShortcut): string;
333
- //#endregion
334
- //#region src/core/keyboard/matcher.d.ts
335
322
  /**
336
323
  * Tests whether a KeyboardEvent exactly matches a ParsedShortcut,
337
324
  * comparing all four modifier keys (meta, ctrl, shift, alt) and the primary key.
@@ -345,8 +332,6 @@ export declare function findMatchingShortcut(event: KeyboardEvent, shortcuts: re
345
332
  * mapGroupBy returns a Map directly — no Object.entries conversion needed.
346
333
  */
347
334
  export declare function detectConflicts(shortcuts: readonly ParsedShortcut[]): ReadonlyMap<string, readonly ParsedShortcut[]>;
348
- //#endregion
349
- //#region src/core/keyboard/index.d.ts
350
335
  interface ShortcutBinding {
351
336
  readonly shortcut: ParsedShortcut;
352
337
  readonly itemId: ItemId;
@@ -355,7 +340,7 @@ interface ShortcutBinding {
355
340
  /**
356
341
  * Manages keyboard shortcut bindings with global keydown listening.
357
342
  * Supports `using` for automatic cleanup of both individual bindings and the
358
- * global document listener. Detects conflicts via Map.groupBy (ES2026).
343
+ * global document listener. Detects conflicts with the local mapGroupBy helper (core/utils/group-by.ts).
359
344
  */
360
345
  export declare class KeyboardShortcutRegistry implements Disposable {
361
346
  #private;
@@ -376,8 +361,6 @@ export declare class KeyboardShortcutRegistry implements Disposable {
376
361
  getBindings(): ReadonlyMap<string, ShortcutBinding>;
377
362
  [Symbol.dispose](): void;
378
363
  }
379
- //#endregion
380
- //#region src/core/registry.d.ts
381
364
  /**
382
365
  * Manages registration and lookup of command items and groups.
383
366
  * Uses set operation helpers (union/intersection/difference) for efficient ID operations.
@@ -431,8 +414,6 @@ export declare class CommandRegistry implements Disposable {
431
414
  clear(): void;
432
415
  [Symbol.dispose](): void;
433
416
  }
434
- //#endregion
435
- //#region src/core/machine.d.ts
436
417
  /** Command machine — explicit resource management via `using` */
437
418
  interface CommandMachine extends Disposable {
438
419
  getState(): CommandState;
@@ -460,8 +441,6 @@ interface CommandMachine extends Disposable {
460
441
  * ```
461
442
  */
462
443
  export declare function createCommandMachine(options?: CommandMachineOptions): CommandMachine;
463
- //#endregion
464
- //#region src/core/search/default-scorer.d.ts
465
444
  /**
466
445
  * Public API: scores a command item against a search query.
467
446
  * Multi-strategy: exact → prefix → substring → word-boundary → fuzzy.
@@ -469,8 +448,6 @@ export declare function createCommandMachine(options?: CommandMachineOptions): C
469
448
  * which pre-caches lowercase and normalizes query once.
470
449
  */
471
450
  export declare function scoreItem(query: string, item: CommandItem): SearchResult | null;
472
- //#endregion
473
- //#region src/core/search/fuzzy-scorer.d.ts
474
451
  /**
475
452
  * Async-safe fuzzy scorer — wraps scoring in Promise for error resilience.
476
453
  * Falls back gracefully on error via synchronous-throw capture.
@@ -482,8 +459,6 @@ export declare function scoreItemAsync(query: string, item: CommandItem): Promis
482
459
  * entire scoring pipeline in one synchronous pass, wrapped for error safety.
483
460
  */
484
461
  export declare function batchScoreItems(query: string, items: readonly CommandItem[]): Promise<SearchResult[]>;
485
- //#endregion
486
- //#region src/core/search/index.d.ts
487
462
  interface SearchEngineOptions {
488
463
  readonly scorer?: ScorerFn | undefined;
489
464
  }
@@ -491,11 +466,9 @@ interface SearchEngineOptions {
491
466
  * Creates a search engine with pluggable scorer and incremental filtering.
492
467
  * When the query extends the previous one, only prior matches are re-scored.
493
468
  * Pre-caches lowercase at index time — zero toLowerCase() calls during search.
494
- * Uses Iterator Helpers (ES2026) for result pipelines and Set.difference for pruning.
469
+ * Uses Iterator Helpers (ES2025) for result pipelines.
495
470
  */
496
471
  export declare function createSearchEngine(options?: SearchEngineOptions): SearchEngine;
497
- //#endregion
498
- //#region src/core/telemetry.d.ts
499
472
  interface CommandTelemetryHooks {
500
473
  /** Called when the command palette opens */
501
474
  readonly onPaletteOpen?: () => void;
@@ -526,8 +499,6 @@ interface TelemetryMiddleware {
526
499
  * ```
527
500
  */
528
501
  export declare function createTelemetryMiddleware(hooks: CommandTelemetryHooks): TelemetryMiddleware;
529
- //#endregion
530
- //#region src/core/utils/event-emitter.d.ts
531
502
  type EventMap = {
532
503
  [key: string]: unknown;
533
504
  };
@@ -549,8 +520,6 @@ export declare class TypedEmitter<T extends EventMap> implements Disposable {
549
520
  removeAll(): void;
550
521
  [Symbol.dispose](): void;
551
522
  }
552
- //#endregion
553
- //#region src/core/utils/scheduler.d.ts
554
523
  /**
555
524
  * Batched update scheduler that coalesces state updates into a single tick.
556
525
  * Uses requestAnimationFrame in browsers, queueMicrotask in Node.js/tests.
@@ -565,5 +534,4 @@ interface Scheduler extends Disposable {
565
534
  * execution pass using rAF (browser) or queueMicrotask (Node.js).
566
535
  */
567
536
  export declare function createScheduler(): Scheduler;
568
- //#endregion
569
537
  export type { CommandEvent, CommandGroup, CommandItem, CommandMachine, CommandMachineOptions, CommandState, CommandTelemetryHooks, FrecencyData, FrecencyDecayConfig, FrecencyOptions, FrecencyRecord, FrecencyStorage, GroupId, ItemId, ParsedShortcut, Scheduler, ScorerFn, SearchEngine, SearchResult, TelemetryMiddleware };
@@ -1,4 +1,4 @@
1
- //#region src/core/utils/string-wellformed.ts
1
+ // src/core/utils/string-wellformed.ts
2
2
  /**
3
3
  * Regex matching lone surrogates (unpaired high or low surrogates).
4
4
  * A lone high surrogate (U+D800–U+DBFF) not followed by a low surrogate,
@@ -15,8 +15,7 @@ const REPLACEMENT_CHAR = "�";
15
15
  function ensureWellFormed(str) {
16
16
  return str.replace(LONE_SURROGATE_RE, REPLACEMENT_CHAR);
17
17
  }
18
- //#endregion
19
- //#region src/core/frecency/idb-storage.ts
18
+ // src/core/frecency/idb-storage.ts
20
19
  /** Serialize a FrecencyRecord to a JSON-safe format */
21
20
  function serializeRecord(record) {
22
21
  return {
@@ -45,7 +44,7 @@ function storageKey(namespace) {
45
44
  }
46
45
  let idbModule;
47
46
  /**
48
- * IndexedDB-backed frecency storage using idb-keyval 6.2.2.
47
+ * IndexedDB-backed frecency storage using idb-keyval.
49
48
  *
50
49
  * Persists frecency data across browser sessions. Implements both
51
50
  * `Disposable` and `AsyncDisposable` for use with `using` and `await using`.
@@ -119,8 +118,7 @@ var IdbFrecencyStorage = class {
119
118
  this.#disposed = true;
120
119
  }
121
120
  };
122
- //#endregion
123
- //#region src/core/types.ts
121
+ // src/core/types.ts
124
122
  /** Create a branded {@link ItemId} from a plain string. Ensures well-formed Unicode. */
125
123
  function itemId(id) {
126
124
  return ensureWellFormed(id);
@@ -158,8 +156,7 @@ function createInitialState(options) {
158
156
  lastUpdated: Date.now()
159
157
  };
160
158
  }
161
- //#endregion
162
- //#region src/core/frecency/memory-storage.ts
159
+ // src/core/frecency/memory-storage.ts
163
160
  /**
164
161
  * In-memory implementation of FrecencyStorage using a Map.
165
162
  * Data does not persist across page reloads. Suitable for ephemeral
@@ -173,7 +170,7 @@ var MemoryFrecencyStorage = class {
173
170
  save(namespace, data) {
174
171
  this.#store.set(namespace, data);
175
172
  }
176
- /** Serialize all stored data — Iterator Helpers pipeline (ES2026) */
173
+ /** Serialize all stored data — Iterator Helpers pipeline (ES2025) */
177
174
  toJSON() {
178
175
  return Object.fromEntries(this.#store.entries().map(([namespace, data]) => [namespace, { records: data.records.entries().toArray() }]));
179
176
  }
@@ -181,11 +178,10 @@ var MemoryFrecencyStorage = class {
181
178
  this.#store.clear();
182
179
  }
183
180
  };
184
- //#endregion
185
- //#region src/core/frecency/index.ts
181
+ // src/core/frecency/index.ts
186
182
  /** Shared empty bonus map — avoids allocation when no frecency records exist */
187
183
  const EMPTY_BONUS_MAP = /* @__PURE__ */ new Map();
188
- /** Pre-computed bucket boundaries in hours — avoids Duration.total() per call */
184
+ /** Bucket boundaries as hour constants — no per-call unit conversion */
189
185
  const BUCKET_HOURS = {
190
186
  hour: 1,
191
187
  day: 24,
@@ -195,7 +191,7 @@ const BUCKET_HOURS = {
195
191
  /**
196
192
  * Computes a frecency bonus for an item based on usage frequency and recency.
197
193
  * Uses hour/day/week/month bucket boundaries with
198
- * configurable exponential decay weights per time bucket.
194
+ * configurable step weights per recency bucket (hour/day/week/month/older).
199
195
  */
200
196
  function computeFrecencyBonus(history, now = Date.now(), config = DEFAULT_FRECENCY_DECAY) {
201
197
  const hours = (now - history.lastUsed) / 36e5;
@@ -284,8 +280,7 @@ var FrecencyEngine = class {
284
280
  this.#storage[Symbol.dispose]();
285
281
  }
286
282
  };
287
- //#endregion
288
- //#region src/core/utils/group-by.ts
283
+ // src/core/utils/group-by.ts
289
284
  /**
290
285
  * Groups items from an iterable into a Map keyed by the result of `keyFn`.
291
286
  * Cross-browser replacement for `Map.groupBy()`.
@@ -300,8 +295,7 @@ function mapGroupBy(items, keyFn) {
300
295
  }
301
296
  return map;
302
297
  }
303
- //#endregion
304
- //#region src/core/keyboard/matcher.ts
298
+ // src/core/keyboard/matcher.ts
305
299
  /**
306
300
  * Tests whether a KeyboardEvent exactly matches a ParsedShortcut,
307
301
  * comparing all four modifier keys (meta, ctrl, shift, alt) and the primary key.
@@ -326,8 +320,7 @@ function detectConflicts(shortcuts) {
326
320
  const grouped = mapGroupBy(shortcuts, (s) => s.normalized);
327
321
  return new Map(grouped.entries().filter(([, group]) => group.length > 1));
328
322
  }
329
- //#endregion
330
- //#region src/core/keyboard/parser.ts
323
+ // src/core/keyboard/parser.ts
331
324
  const isMac = typeof navigator !== "undefined" && (navigator.userAgentData?.platform === "macOS" || /Mac|iPod|iPhone|iPad/.test(navigator.platform));
332
325
  /** Modifier aliases — cross-platform Mod resolution */
333
326
  const MODIFIER_MAP = {
@@ -400,12 +393,11 @@ function formatShortcut(parsed) {
400
393
  parts.push(displayKey);
401
394
  return isMac ? parts.join("") : parts.join("+");
402
395
  }
403
- //#endregion
404
- //#region src/core/keyboard/index.ts
396
+ // src/core/keyboard/index.ts
405
397
  /**
406
398
  * Manages keyboard shortcut bindings with global keydown listening.
407
399
  * Supports `using` for automatic cleanup of both individual bindings and the
408
- * global document listener. Detects conflicts via Map.groupBy (ES2026).
400
+ * global document listener. Detects conflicts with the local mapGroupBy helper (core/utils/group-by.ts).
409
401
  */
410
402
  var KeyboardShortcutRegistry = class {
411
403
  #bindings = /* @__PURE__ */ new Map();
@@ -472,8 +464,7 @@ var KeyboardShortcutRegistry = class {
472
464
  this.#bindings.clear();
473
465
  }
474
466
  };
475
- //#endregion
476
- //#region src/core/utils/set-ops.ts
467
+ // src/core/utils/set-ops.ts
477
468
  /** Returns a new Set containing elements present in both `a` and `b`. */
478
469
  function setIntersection(a, b) {
479
470
  const result = /* @__PURE__ */ new Set();
@@ -516,8 +507,7 @@ function setSymmetricDifference(a, b) {
516
507
  else result.add(item);
517
508
  return result;
518
509
  }
519
- //#endregion
520
- //#region src/core/registry.ts
510
+ // src/core/registry.ts
521
511
  /**
522
512
  * Manages registration and lookup of command items and groups.
523
513
  * Uses set operation helpers (union/intersection/difference) for efficient ID operations.
@@ -678,8 +668,23 @@ var CommandRegistry = class {
678
668
  this.clear();
679
669
  }
680
670
  };
681
- //#endregion
682
- //#region src/core/search/default-scorer.ts
671
+ // src/core/utils/env.ts
672
+ /**
673
+ * `true` unless `process.env.NODE_ENV` is `'production'`.
674
+ *
675
+ * Consumer bundlers (Vite, webpack, Next, esbuild) replace `process.env.NODE_ENV` statically,
676
+ * so the dev-only branches guarded by this flag fold away in production builds. A browser
677
+ * running the unbundled module throws a ReferenceError on the bare `process` reference;
678
+ * the catch turns that into the production value (`false`), so dev-only code stays off.
679
+ */
680
+ const isDev = (() => {
681
+ try {
682
+ return process.env.NODE_ENV !== "production";
683
+ } catch {
684
+ return false;
685
+ }
686
+ })();
687
+ // src/core/search/default-scorer.ts
683
688
  function isWordSeparator(code) {
684
689
  return code === 32 || code === 9 || code === 45 || code === 95 || code === 46 || code === 47 || code === 92;
685
690
  }
@@ -841,18 +846,16 @@ function scoreFuzzy(query, qLen, lowerTarget, tLen) {
841
846
  matches
842
847
  };
843
848
  }
844
- //#endregion
845
- //#region src/core/search/index.ts
846
- const __DEV__ = globalThis.process ? globalThis.process.env.NODE_ENV !== "production" : false;
849
+ // src/core/search/index.ts
847
850
  let leakRegistry;
848
- if (__DEV__) leakRegistry = new FinalizationRegistry((label) => {
851
+ if (isDev && typeof window !== "undefined") leakRegistry = new FinalizationRegistry((label) => {
849
852
  console.warn(`[modern-cmdk] ${label} was garbage collected without being disposed. Use \`using\` or call [Symbol.dispose]() to prevent leaks.`);
850
853
  });
851
854
  /**
852
855
  * Creates a search engine with pluggable scorer and incremental filtering.
853
856
  * When the query extends the previous one, only prior matches are re-scored.
854
857
  * Pre-caches lowercase at index time — zero toLowerCase() calls during search.
855
- * Uses Iterator Helpers (ES2026) for result pipelines and Set.difference for pruning.
858
+ * Uses Iterator Helpers (ES2025) for result pipelines.
856
859
  */
857
860
  function createSearchEngine(options) {
858
861
  const customScorer = options?.scorer;
@@ -861,7 +864,7 @@ function createSearchEngine(options) {
861
864
  let previousQuery = "";
862
865
  let previousResults = /* @__PURE__ */ new Set();
863
866
  const sentinel = {};
864
- if (__DEV__ && leakRegistry) leakRegistry.register(sentinel, "SearchEngine", sentinel);
867
+ if (leakRegistry) leakRegistry.register(sentinel, "SearchEngine", sentinel);
865
868
  return {
866
869
  index(items) {
867
870
  for (const item of items) indexedEntries.set(item.id, {
@@ -911,12 +914,11 @@ function createSearchEngine(options) {
911
914
  [Symbol.dispose]() {
912
915
  indexedEntries.clear();
913
916
  previousResults.clear();
914
- if (__DEV__ && leakRegistry) leakRegistry.unregister(sentinel);
917
+ if (leakRegistry) leakRegistry.unregister(sentinel);
915
918
  }
916
919
  };
917
920
  }
918
- //#endregion
919
- //#region src/core/utils/event-emitter.ts
921
+ // src/core/utils/event-emitter.ts
920
922
  /**
921
923
  * Type-safe event emitter with strong references and Disposable subscriptions.
922
924
  * Returns Disposable from `on()` for automatic unsubscription via `using`.
@@ -959,13 +961,13 @@ var TypedEmitter = class {
959
961
  this.#listeners.clear();
960
962
  }
961
963
  };
962
- //#endregion
963
- //#region src/core/utils/scheduler.ts
964
+ // src/core/utils/scheduler.ts
964
965
  /** Whether we're in a browser environment with rAF available */
965
966
  const hasRAF = typeof requestAnimationFrame === "function";
966
- /** Feature detection for cutting-edge scheduling APIs */
967
+ /** Feature detection for cutting-edge scheduling APIs, read through globalThis: typeof guards only a bare
968
+ * identifier, so `typeof navigator?.scheduling` would throw where navigator is undeclared (runtimes without one). */
967
969
  const canYield = typeof globalThis.scheduler?.yield === "function";
968
- const hasInputPending = typeof navigator?.scheduling?.isInputPending === "function";
970
+ const hasInputPending = typeof globalThis.navigator?.scheduling?.isInputPending === "function";
969
971
  /**
970
972
  * Creates a batched update scheduler. Coalesces rapid state updates into a single
971
973
  * execution pass using rAF (browser) or queueMicrotask (Node.js).
@@ -1021,8 +1023,7 @@ function createScheduler() {
1021
1023
  }
1022
1024
  };
1023
1025
  }
1024
- //#endregion
1025
- //#region src/core/machine.ts
1026
+ // src/core/machine.ts
1026
1027
  /**
1027
1028
  * Creates a headless command palette state machine with search, frecency,
1028
1029
  * and keyboard shortcut support. Implements Disposable for `using` cleanup.
@@ -1288,8 +1289,7 @@ function createCommandMachine(options = {}) {
1288
1289
  }
1289
1290
  };
1290
1291
  }
1291
- //#endregion
1292
- //#region src/core/search/fuzzy-scorer.ts
1292
+ // src/core/search/fuzzy-scorer.ts
1293
1293
  /**
1294
1294
  * Async-safe fuzzy scorer — wraps scoring in Promise for error resilience.
1295
1295
  * Falls back gracefully on error via synchronous-throw capture.
@@ -1309,8 +1309,7 @@ function batchScoreItems(query, items) {
1309
1309
  resolve(items.values().map((item) => scoreItem(query, item)).filter((r) => r != null).toArray().toSorted((a, b) => b.score - a.score));
1310
1310
  });
1311
1311
  }
1312
- //#endregion
1313
- //#region src/core/telemetry.ts
1312
+ // src/core/telemetry.ts
1314
1313
  /**
1315
1314
  * Creates a telemetry middleware that measures command palette interactions.
1316
1315
  * Uses Date.now() for millisecond-precision timestamps
@@ -1347,5 +1346,4 @@ function createTelemetryMiddleware(hooks) {
1347
1346
  }
1348
1347
  };
1349
1348
  }
1350
- //#endregion
1351
1349
  export { CommandRegistry, DEFAULT_FRECENCY_DECAY, DEFAULT_MACHINE_OPTIONS, FrecencyEngine, IdbFrecencyStorage, KeyboardShortcutRegistry, MemoryFrecencyStorage, TypedEmitter, batchScoreItems, computeFrecencyBonus, createCommandMachine, createInitialState, createScheduler, createSearchEngine, createTelemetryMiddleware, detectConflicts, findMatchingShortcut, formatShortcut, groupId, itemId, matchesShortcut, parseShortcut, scoreItem, scoreItemAsync };