@inseefr/lunatic 3.7.6-rc.alphanumeric-sorting → 3.7.6-rc.alphanumeric-sorting.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,8 +3,9 @@
3
3
  *
4
4
  * 1. Sort by melauto score
5
5
  * 2. When scores are equal, sort alphabetically with numeric awareness
6
- * This ensures consistent ordering for numeric queries
6
+ * This ensures consistent ordering for items with identical scores
7
7
  * (e.g., "0111Z" will appear before "0115Z" when both match "011")
8
+ * Numeric awareness means "item2" will come before "item10" (not "item10" before "item2")
8
9
  */
9
10
  export declare function applyMelauto<T extends {
10
11
  id: string;
@@ -3,8 +3,9 @@
3
3
  *
4
4
  * 1. Sort by melauto score
5
5
  * 2. When scores are equal, sort alphabetically with numeric awareness
6
- * This ensures consistent ordering for numeric queries
6
+ * This ensures consistent ordering for items with identical scores
7
7
  * (e.g., "0111Z" will appear before "0115Z" when both match "011")
8
+ * Numeric awareness means "item2" will come before "item10" (not "item10" before "item2")
8
9
  */
9
10
  export function applyMelauto(query, data) {
10
11
  return data.sort((a, b) => {
@@ -14,7 +15,7 @@ export function applyMelauto(query, data) {
14
15
  const diff = sb - sa;
15
16
  if (diff !== 0)
16
17
  return diff;
17
- // This ensures stable sorting when multiple items have the same score
18
+ // If scores are equals: alphanumeric sort with numeric awareness
18
19
  const ta = ((_c = a.label) !== null && _c !== void 0 ? _c : a.id).toString();
19
20
  const tb = ((_d = b.label) !== null && _d !== void 0 ? _d : b.id).toString();
20
21
  return ta.localeCompare(tb, undefined, {
@@ -1 +1 @@
1
- {"version":3,"file":"melauto.js","sourceRoot":"","sources":["../../../src/utils/search/melauto.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC3B,KAAa,EACb,IAAS;IAET,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;;QACzB,MAAM,EAAE,GAAG,YAAY,CAAC,MAAA,CAAC,CAAC,KAAK,mCAAI,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,YAAY,CAAC,MAAA,CAAC,CAAC,KAAK,mCAAI,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC;QACrB,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5B,sEAAsE;QACtE,MAAM,EAAE,GAAG,CAAC,MAAA,CAAC,CAAC,KAAK,mCAAI,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,EAAE,GAAG,CAAC,MAAA,CAAC,CAAC,KAAK,mCAAI,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE;YACtC,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AACD;;;GAGG;AACH,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE;IACzC,OAAO,GAAG;SACR,SAAS,CAAC,KAAK,CAAC;SAChB,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;SAC/B,WAAW,EAAE;SACb,KAAK,CAAC,YAAY,CAAC;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SAC3B,IAAI,CAAC,GAAG,CAAC,CAAC;AACb,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,KAAa;IACtD,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,UAAU,CAAC,MAAM,CAAC,UAAU,KAAK,EAAE,KAAK,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACf,OAAO,KAAK,CAAC;QACd,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;QAC5D,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;QAC3D,OAAO,KAAK,GAAG,GAAG,GAAG,MAAM,CAAC;IAC7B,CAAC,EAAE,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"melauto.js","sourceRoot":"","sources":["../../../src/utils/search/melauto.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAC3B,KAAa,EACb,IAAS;IAET,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;;QACzB,MAAM,EAAE,GAAG,YAAY,CAAC,MAAA,CAAC,CAAC,KAAK,mCAAI,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,YAAY,CAAC,MAAA,CAAC,CAAC,KAAK,mCAAI,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC;QACrB,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE5B,iEAAiE;QACjE,MAAM,EAAE,GAAG,CAAC,MAAA,CAAC,CAAC,KAAK,mCAAI,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,EAAE,GAAG,CAAC,MAAA,CAAC,CAAC,KAAK,mCAAI,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE;YACtC,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE;IACzC,OAAO,GAAG;SACR,SAAS,CAAC,KAAK,CAAC;SAChB,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;SAC/B,WAAW,EAAE;SACb,KAAK,CAAC,YAAY,CAAC;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SAC3B,IAAI,CAAC,GAAG,CAAC,CAAC;AACb,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,KAAa;IACtD,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,UAAU,CAAC,MAAM,CAAC,UAAU,KAAK,EAAE,KAAK,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACf,OAAO,KAAK,CAAC;QACd,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;QAC5D,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;QAC3D,OAAO,KAAK,GAAG,GAAG,GAAG,MAAM,CAAC;IAC7B,CAAC,EAAE,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -69,5 +69,35 @@ describe('melautoScore', () => {
69
69
  ];
70
70
  expect(sortedData).toStrictEqual(expectedSortedData);
71
71
  });
72
+ it('should apply alphanumeric sort with numeric awareness', () => {
73
+ const mixedData = [
74
+ { id: 'code10', label: 'code10' },
75
+ { id: 'code2', label: 'code2' },
76
+ { id: 'code20', label: 'code20' },
77
+ ];
78
+ const sorted = applyMelauto('code', mixedData);
79
+ // Should sort numerically: code2, code10, code20
80
+ expect(sorted.map((d) => d.id)).toStrictEqual([
81
+ 'code2',
82
+ 'code10',
83
+ 'code20',
84
+ ]);
85
+ });
86
+ it('should handle mixed alphanumeric queries with numeric sorting', () => {
87
+ const data = [
88
+ { id: 'item10B', label: 'item10B' },
89
+ { id: 'item2A', label: 'item2A' },
90
+ { id: 'item20C', label: 'item20C' },
91
+ { id: 'item3D', label: 'item3D' },
92
+ ];
93
+ const sortedData = applyMelauto('item2', data);
94
+ // "item2A" scores highest (exact match), others sorted alphanumerically
95
+ expect(sortedData.map((d) => d.id)).toStrictEqual([
96
+ 'item2A',
97
+ 'item20C',
98
+ 'item3D',
99
+ 'item10B',
100
+ ]);
101
+ });
72
102
  });
73
103
  //# sourceMappingURL=melauto.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"melauto.spec.js","sourceRoot":"","sources":["../../../src/utils/search/melauto.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"melauto.spec.js","sourceRoot":"","sources":["../../../src/utils/search/melauto.spec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inseefr/lunatic",
3
- "version": "3.7.6-rc.alphanumeric-sorting",
3
+ "version": "3.7.6-rc.alphanumeric-sorting.1",
4
4
  "description": "Library of questionnaire components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -78,4 +78,37 @@ describe('melautoScore', () => {
78
78
  ];
79
79
  expect(sortedData).toStrictEqual(expectedSortedData);
80
80
  });
81
+
82
+ it('should apply alphanumeric sort with numeric awareness', () => {
83
+ const mixedData = [
84
+ { id: 'code10', label: 'code10' },
85
+ { id: 'code2', label: 'code2' },
86
+ { id: 'code20', label: 'code20' },
87
+ ];
88
+
89
+ const sorted = applyMelauto('code', mixedData);
90
+ // Should sort numerically: code2, code10, code20
91
+ expect(sorted.map((d) => d.id)).toStrictEqual([
92
+ 'code2',
93
+ 'code10',
94
+ 'code20',
95
+ ]);
96
+ });
97
+
98
+ it('should handle mixed alphanumeric queries with numeric sorting', () => {
99
+ const data = [
100
+ { id: 'item10B', label: 'item10B' },
101
+ { id: 'item2A', label: 'item2A' },
102
+ { id: 'item20C', label: 'item20C' },
103
+ { id: 'item3D', label: 'item3D' },
104
+ ];
105
+ const sortedData = applyMelauto('item2', data);
106
+ // "item2A" scores highest (exact match), others sorted alphanumerically
107
+ expect(sortedData.map((d) => d.id)).toStrictEqual([
108
+ 'item2A',
109
+ 'item20C',
110
+ 'item3D',
111
+ 'item10B',
112
+ ]);
113
+ });
81
114
  });
@@ -3,8 +3,9 @@
3
3
  *
4
4
  * 1. Sort by melauto score
5
5
  * 2. When scores are equal, sort alphabetically with numeric awareness
6
- * This ensures consistent ordering for numeric queries
6
+ * This ensures consistent ordering for items with identical scores
7
7
  * (e.g., "0111Z" will appear before "0115Z" when both match "011")
8
+ * Numeric awareness means "item2" will come before "item10" (not "item10" before "item2")
8
9
  */
9
10
  export function applyMelauto<T extends { id: string; label?: string }>(
10
11
  query: string,
@@ -15,7 +16,8 @@ export function applyMelauto<T extends { id: string; label?: string }>(
15
16
  const sb = melautoScore(b.label ?? b.id, query);
16
17
  const diff = sb - sa;
17
18
  if (diff !== 0) return diff;
18
- // This ensures stable sorting when multiple items have the same score
19
+
20
+ // If scores are equals: alphanumeric sort with numeric awareness
19
21
  const ta = (a.label ?? a.id).toString();
20
22
  const tb = (b.label ?? b.id).toString();
21
23
  return ta.localeCompare(tb, undefined, {
@@ -24,6 +26,7 @@ export function applyMelauto<T extends { id: string; label?: string }>(
24
26
  });
25
27
  });
26
28
  }
29
+
27
30
  /**
28
31
  * Normalize a string to remove accent and other unicode character
29
32
  * "Héllo (wörld)" becomes "Hello world"