@neuledge/context 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/store.d.ts CHANGED
@@ -12,22 +12,47 @@ export interface PackageInfo extends PackageMeta {
12
12
  }
13
13
  /** Create a filesystem-safe filename for an installed package database. */
14
14
  export declare function getPackageFileName(name: string, version: string): string;
15
+ /** Identity of an installed package, and the spec users type: `name@version`. */
16
+ export declare function packageKey(pkg: PackageMeta): string;
17
+ /**
18
+ * Match a package against a `--libs` allow-list holding bare names (every
19
+ * installed version) and `name@version` keys (that version only).
20
+ */
21
+ export declare function isAllowedLibrary(pkg: PackageMeta, allowed: ReadonlySet<string>): boolean;
22
+ /**
23
+ * Order two version strings, lowest first.
24
+ *
25
+ * Rules, all chosen so a bare-name lookup lands on the version a user expects:
26
+ * - segments compare as numbers, so `1.15.9` < `1.15.10` (text order gets this
27
+ * backwards — the bug behind #102);
28
+ * - a missing segment counts as zero, so `1.2` and `1.2.0` are the same release;
29
+ * - a prerelease sorts below its release (`2.0.0-rc.1` < `2.0.0`); two
30
+ * prereleases compare as text;
31
+ * - versions with no numeric part (`latest`, `main`) sort below every numeric
32
+ * version, so a floating label never hides a real release;
33
+ * - anything still tied falls back to text, so results never depend on
34
+ * insertion or filesystem order.
35
+ */
36
+ export declare function compareVersions(a: string, b: string): number;
15
37
  /**
16
38
  * Registry of documentation packages.
17
39
  * Manages an in-memory list of packages without file system operations.
18
40
  */
19
41
  export declare class PackageStore {
20
42
  private packages;
21
- /** Add a package to the registry. */
43
+ /** Add a package to the registry. Replaces the same name@version only. */
22
44
  add(info: PackageInfo): void;
23
- /** Remove a package from the registry by name. Returns true if removed. */
24
- remove(name: string): boolean;
25
- /** Get all registered packages. */
45
+ /** Remove a package resolved from `spec` (see `get`). Returns true if removed. */
46
+ remove(spec: string): boolean;
47
+ /** Get all registered packages, grouped by name with the highest version first. */
26
48
  list(): PackageInfo[];
27
- /** Get a package by name. */
28
- get(name: string): PackageInfo | null;
29
- /** Open a package database for searching. */
30
- openDb(name: string): DatabaseConnection | null;
49
+ /**
50
+ * Get a package by spec: `name@version` returns that exact version, a bare
51
+ * `name` returns the highest installed version.
52
+ */
53
+ get(spec: string): PackageInfo | null;
54
+ /** Open a package database for searching. Accepts the same specs as `get`. */
55
+ openDb(spec: string): DatabaseConnection | null;
31
56
  }
32
57
  /** Read package info from a database file. */
33
58
  export declare function readPackageInfo(packagePath: string): PackageInfo;
package/dist/store.js CHANGED
@@ -7,31 +7,114 @@ export function getPackageFileName(name, version) {
7
7
  const safeVersion = version.replaceAll("/", "__");
8
8
  return `${safeName}@${safeVersion}.db`;
9
9
  }
10
+ /** Identity of an installed package, and the spec users type: `name@version`. */
11
+ export function packageKey(pkg) {
12
+ return `${pkg.name}@${pkg.version}`;
13
+ }
14
+ /**
15
+ * Match a package against a `--libs` allow-list holding bare names (every
16
+ * installed version) and `name@version` keys (that version only).
17
+ */
18
+ export function isAllowedLibrary(pkg, allowed) {
19
+ return allowed.has(pkg.name) || allowed.has(packageKey(pkg));
20
+ }
21
+ /** Numeric segments of a version plus its prerelease suffix, or null if not numeric. */
22
+ function parseVersionParts(version) {
23
+ const core = version.startsWith("v") ? version.slice(1) : version;
24
+ const dash = core.indexOf("-");
25
+ const segments = (dash === -1 ? core : core.slice(0, dash)).split(".");
26
+ if (!segments.every((s) => /^\d+$/.test(s)))
27
+ return null;
28
+ return {
29
+ numbers: segments.map((s) => Number.parseInt(s, 10)),
30
+ prerelease: dash === -1 ? "" : core.slice(dash + 1),
31
+ };
32
+ }
33
+ function compareText(a, b) {
34
+ return a < b ? -1 : a > b ? 1 : 0;
35
+ }
36
+ /**
37
+ * Order two version strings, lowest first.
38
+ *
39
+ * Rules, all chosen so a bare-name lookup lands on the version a user expects:
40
+ * - segments compare as numbers, so `1.15.9` < `1.15.10` (text order gets this
41
+ * backwards — the bug behind #102);
42
+ * - a missing segment counts as zero, so `1.2` and `1.2.0` are the same release;
43
+ * - a prerelease sorts below its release (`2.0.0-rc.1` < `2.0.0`); two
44
+ * prereleases compare as text;
45
+ * - versions with no numeric part (`latest`, `main`) sort below every numeric
46
+ * version, so a floating label never hides a real release;
47
+ * - anything still tied falls back to text, so results never depend on
48
+ * insertion or filesystem order.
49
+ */
50
+ export function compareVersions(a, b) {
51
+ const partsA = parseVersionParts(a);
52
+ const partsB = parseVersionParts(b);
53
+ if (!partsA || !partsB) {
54
+ if (partsA)
55
+ return 1;
56
+ if (partsB)
57
+ return -1;
58
+ return compareText(a, b);
59
+ }
60
+ const length = Math.max(partsA.numbers.length, partsB.numbers.length);
61
+ for (let i = 0; i < length; i++) {
62
+ const diff = (partsA.numbers[i] ?? 0) - (partsB.numbers[i] ?? 0);
63
+ if (diff !== 0)
64
+ return diff;
65
+ }
66
+ if (partsA.prerelease !== partsB.prerelease) {
67
+ if (!partsA.prerelease)
68
+ return 1;
69
+ if (!partsB.prerelease)
70
+ return -1;
71
+ return compareText(partsA.prerelease, partsB.prerelease);
72
+ }
73
+ return compareText(a, b);
74
+ }
10
75
  /**
11
76
  * Registry of documentation packages.
12
77
  * Manages an in-memory list of packages without file system operations.
13
78
  */
14
79
  export class PackageStore {
80
+ // Keyed by `name@version`: several versions of the same package can be
81
+ // installed side by side, and each one has to stay addressable.
15
82
  packages = new Map();
16
- /** Add a package to the registry. */
83
+ /** Add a package to the registry. Replaces the same name@version only. */
17
84
  add(info) {
18
- this.packages.set(info.name, info);
85
+ this.packages.set(packageKey(info), info);
19
86
  }
20
- /** Remove a package from the registry by name. Returns true if removed. */
21
- remove(name) {
22
- return this.packages.delete(name);
87
+ /** Remove a package resolved from `spec` (see `get`). Returns true if removed. */
88
+ remove(spec) {
89
+ const pkg = this.get(spec);
90
+ if (!pkg)
91
+ return false;
92
+ return this.packages.delete(packageKey(pkg));
23
93
  }
24
- /** Get all registered packages. */
94
+ /** Get all registered packages, grouped by name with the highest version first. */
25
95
  list() {
26
- return [...this.packages.values()].sort((a, b) => a.name.localeCompare(b.name));
96
+ return [...this.packages.values()].sort((a, b) => a.name.localeCompare(b.name) || compareVersions(b.version, a.version));
27
97
  }
28
- /** Get a package by name. */
29
- get(name) {
30
- return this.packages.get(name) ?? null;
98
+ /**
99
+ * Get a package by spec: `name@version` returns that exact version, a bare
100
+ * `name` returns the highest installed version.
101
+ */
102
+ get(spec) {
103
+ const exact = this.packages.get(spec);
104
+ if (exact)
105
+ return exact;
106
+ let best = null;
107
+ for (const pkg of this.packages.values()) {
108
+ if (pkg.name !== spec)
109
+ continue;
110
+ if (!best || compareVersions(pkg.version, best.version) > 0)
111
+ best = pkg;
112
+ }
113
+ return best;
31
114
  }
32
- /** Open a package database for searching. */
33
- openDb(name) {
34
- const pkg = this.packages.get(name);
115
+ /** Open a package database for searching. Accepts the same specs as `get`. */
116
+ openDb(spec) {
117
+ const pkg = this.get(spec);
35
118
  if (!pkg)
36
119
  return null;
37
120
  return openDatabase(pkg.path, { readonly: true });
package/dist/store.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAA2B,YAAY,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAe/E,2EAA2E;AAC3E,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,OAAe;IAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAClD,OAAO,GAAG,QAAQ,IAAI,WAAW,KAAK,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,YAAY;IACf,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IAElD,qCAAqC;IACrC,GAAG,CAAC,IAAiB;QACnB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,2EAA2E;IAC3E,MAAM,CAAC,IAAY;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,mCAAmC;IACnC,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC/C,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAC7B,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IACzC,CAAC;IAED,6CAA6C;IAC7C,MAAM,CAAC,IAAY;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;CACF;AAED,8CAA8C;AAC9C,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,EAAE,GAAG,YAAY,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,qBAAqB,CAAC,EAAE,CAAC,CAAC;QAE1B,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAE5C,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;QAED,OAAO;YACL,IAAI;YACJ,OAAO;YACP,WAAW,EAAE,YAAY,CAAC,EAAE,EAAE,aAAa,CAAC;YAC5C,SAAS,EAAE,YAAY,CAAC,EAAE,EAAE,YAAY,CAAC;YACzC,IAAI,EAAE,WAAW;YACjB,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,IAAI;YACrC,YAAY,EAAE,eAAe,CAAC,EAAE,CAAC;SAClC,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neuledge/context",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "mcpName": "io.github.neuledge/context",
5
5
  "description": "Context management for Neuledge packages",
6
6
  "keywords": [],