modern-cmdk 1.2.1 → 1.2.3

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,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 {
@@ -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
@@ -181,8 +178,7 @@ 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
184
  /** Pre-computed bucket boundaries in hours — avoids Duration.total() per call */
@@ -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 = {
@@ -366,9 +359,7 @@ function parseShortcut(shortcut) {
366
359
  case "shift":
367
360
  shift = true;
368
361
  break;
369
- case "alt":
370
- alt = true;
371
- break;
362
+ case "alt": alt = true;
372
363
  }
373
364
  else key = part;
374
365
  }
@@ -402,8 +393,7 @@ function formatShortcut(parsed) {
402
393
  parts.push(displayKey);
403
394
  return isMac ? parts.join("") : parts.join("+");
404
395
  }
405
- //#endregion
406
- //#region src/core/keyboard/index.ts
396
+ // src/core/keyboard/index.ts
407
397
  /**
408
398
  * Manages keyboard shortcut bindings with global keydown listening.
409
399
  * Supports `using` for automatic cleanup of both individual bindings and the
@@ -474,8 +464,7 @@ var KeyboardShortcutRegistry = class {
474
464
  this.#bindings.clear();
475
465
  }
476
466
  };
477
- //#endregion
478
- //#region src/core/utils/set-ops.ts
467
+ // src/core/utils/set-ops.ts
479
468
  /** Returns a new Set containing elements present in both `a` and `b`. */
480
469
  function setIntersection(a, b) {
481
470
  const result = /* @__PURE__ */ new Set();
@@ -518,8 +507,7 @@ function setSymmetricDifference(a, b) {
518
507
  else result.add(item);
519
508
  return result;
520
509
  }
521
- //#endregion
522
- //#region src/core/registry.ts
510
+ // src/core/registry.ts
523
511
  /**
524
512
  * Manages registration and lookup of command items and groups.
525
513
  * Uses set operation helpers (union/intersection/difference) for efficient ID operations.
@@ -680,8 +668,23 @@ var CommandRegistry = class {
680
668
  this.clear();
681
669
  }
682
670
  };
683
- //#endregion
684
- //#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
685
688
  function isWordSeparator(code) {
686
689
  return code === 32 || code === 9 || code === 45 || code === 95 || code === 46 || code === 47 || code === 92;
687
690
  }
@@ -843,11 +846,9 @@ function scoreFuzzy(query, qLen, lowerTarget, tLen) {
843
846
  matches
844
847
  };
845
848
  }
846
- //#endregion
847
- //#region src/core/search/index.ts
848
- const __DEV__ = globalThis.process ? globalThis.process.env.NODE_ENV !== "production" : false;
849
+ // src/core/search/index.ts
849
850
  let leakRegistry;
850
- if (__DEV__) leakRegistry = new FinalizationRegistry((label) => {
851
+ if (isDev && typeof window !== "undefined") leakRegistry = new FinalizationRegistry((label) => {
851
852
  console.warn(`[modern-cmdk] ${label} was garbage collected without being disposed. Use \`using\` or call [Symbol.dispose]() to prevent leaks.`);
852
853
  });
853
854
  /**
@@ -863,7 +864,7 @@ function createSearchEngine(options) {
863
864
  let previousQuery = "";
864
865
  let previousResults = /* @__PURE__ */ new Set();
865
866
  const sentinel = {};
866
- if (__DEV__ && leakRegistry) leakRegistry.register(sentinel, "SearchEngine", sentinel);
867
+ if (leakRegistry) leakRegistry.register(sentinel, "SearchEngine", sentinel);
867
868
  return {
868
869
  index(items) {
869
870
  for (const item of items) indexedEntries.set(item.id, {
@@ -913,12 +914,11 @@ function createSearchEngine(options) {
913
914
  [Symbol.dispose]() {
914
915
  indexedEntries.clear();
915
916
  previousResults.clear();
916
- if (__DEV__ && leakRegistry) leakRegistry.unregister(sentinel);
917
+ if (leakRegistry) leakRegistry.unregister(sentinel);
917
918
  }
918
919
  };
919
920
  }
920
- //#endregion
921
- //#region src/core/utils/event-emitter.ts
921
+ // src/core/utils/event-emitter.ts
922
922
  /**
923
923
  * Type-safe event emitter with strong references and Disposable subscriptions.
924
924
  * Returns Disposable from `on()` for automatic unsubscription via `using`.
@@ -961,8 +961,7 @@ var TypedEmitter = class {
961
961
  this.#listeners.clear();
962
962
  }
963
963
  };
964
- //#endregion
965
- //#region src/core/utils/scheduler.ts
964
+ // src/core/utils/scheduler.ts
966
965
  /** Whether we're in a browser environment with rAF available */
967
966
  const hasRAF = typeof requestAnimationFrame === "function";
968
967
  /** Feature detection for cutting-edge scheduling APIs */
@@ -1023,8 +1022,7 @@ function createScheduler() {
1023
1022
  }
1024
1023
  };
1025
1024
  }
1026
- //#endregion
1027
- //#region src/core/machine.ts
1025
+ // src/core/machine.ts
1028
1026
  /**
1029
1027
  * Creates a headless command palette state machine with search, frecency,
1030
1028
  * and keyboard shortcut support. Implements Disposable for `using` cleanup.
@@ -1131,9 +1129,10 @@ function createCommandMachine(options = {}) {
1131
1129
  const loop = options.loop ?? true;
1132
1130
  const currentIdx = activeId ? filteredIdIndex.get(activeId) ?? -1 : -1;
1133
1131
  let newIdx;
1134
- if (direction === "next") if (currentIdx === -1 || currentIdx >= filteredIds.length - 1) newIdx = loop ? 0 : filteredIds.length - 1;
1135
- else newIdx = currentIdx + 1;
1136
- else if (currentIdx <= 0) newIdx = loop ? filteredIds.length - 1 : 0;
1132
+ if (direction === "next") {
1133
+ if (currentIdx === -1 || currentIdx >= filteredIds.length - 1) newIdx = loop ? 0 : filteredIds.length - 1;
1134
+ else newIdx = currentIdx + 1;
1135
+ } else if (currentIdx <= 0) newIdx = loop ? filteredIds.length - 1 : 0;
1137
1136
  else newIdx = currentIdx - 1;
1138
1137
  const newActiveId = filteredIds[newIdx] ?? null;
1139
1138
  if (newActiveId !== activeId) {
@@ -1249,7 +1248,6 @@ function createCommandMachine(options = {}) {
1249
1248
  case "UNREGISTER_GROUP":
1250
1249
  registry.unregisterGroup(event.id);
1251
1250
  refilter(state.search);
1252
- break;
1253
1251
  }
1254
1252
  }
1255
1253
  return {
@@ -1290,8 +1288,7 @@ function createCommandMachine(options = {}) {
1290
1288
  }
1291
1289
  };
1292
1290
  }
1293
- //#endregion
1294
- //#region src/core/search/fuzzy-scorer.ts
1291
+ // src/core/search/fuzzy-scorer.ts
1295
1292
  /**
1296
1293
  * Async-safe fuzzy scorer — wraps scoring in Promise for error resilience.
1297
1294
  * Falls back gracefully on error via synchronous-throw capture.
@@ -1311,8 +1308,7 @@ function batchScoreItems(query, items) {
1311
1308
  resolve(items.values().map((item) => scoreItem(query, item)).filter((r) => r != null).toArray().toSorted((a, b) => b.score - a.score));
1312
1309
  });
1313
1310
  }
1314
- //#endregion
1315
- //#region src/core/telemetry.ts
1311
+ // src/core/telemetry.ts
1316
1312
  /**
1317
1313
  * Creates a telemetry middleware that measures command palette interactions.
1318
1314
  * Uses Date.now() for millisecond-precision timestamps
@@ -1349,5 +1345,4 @@ function createTelemetryMiddleware(hooks) {
1349
1345
  }
1350
1346
  };
1351
1347
  }
1352
- //#endregion
1353
1348
  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 };