@agent-device/proxy 0.0.0-stage → 0.21.23

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.
@@ -0,0 +1,179 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ //#region ../host-kit/src/internal/project-root.ts
5
+ function resolveAgentDeviceProjectRoot(startDirectory) {
6
+ let current = startDirectory;
7
+ let nearest = null;
8
+ for (let i = 0; i < 8; i += 1) {
9
+ const pkgPath = path.join(current, "package.json");
10
+ if (fs.existsSync(pkgPath)) {
11
+ nearest ??= current;
12
+ try {
13
+ if (JSON.parse(fs.readFileSync(pkgPath, "utf8")).name === "agent-device") return current;
14
+ } catch {}
15
+ }
16
+ current = path.dirname(current);
17
+ }
18
+ return nearest ?? startDirectory;
19
+ }
20
+ /**
21
+ * The daemon's own source, relative to a project root. One path answers two questions
22
+ * with it: whether a tree is a source checkout at all, and which entry a checkout
23
+ * launches its daemon from (`src/daemon-client/daemon-launch-spec.ts`).
24
+ */
25
+ const DAEMON_SOURCE_ENTRY = "src/daemon.ts";
26
+ /**
27
+ * Whether `root` is a source checkout rather than an installed copy of a published
28
+ * version. The published package ships its `bin` and `dist` and no `src`, so the
29
+ * daemon's own source is what tells the two apart — and that is the difference between
30
+ * a tree whose code can be rebuilt under its own version and one whose version already
31
+ * fixes its bytes.
32
+ */
33
+ function isSourceCheckoutProjectRoot(root) {
34
+ return fs.existsSync(path.join(root, "package.json")) && fs.existsSync(path.join(root, "src/daemon.ts"));
35
+ }
36
+ //#endregion
37
+ //#region ../kernel/src/ttl-memo.ts
38
+ const processMemoResets = /* @__PURE__ */ new Set();
39
+ function createTtlMemo(options = {}) {
40
+ const entries = /* @__PURE__ */ new Map();
41
+ const now = options.now ?? (() => Date.now());
42
+ const clearEntryTimer = (entry) => {
43
+ if (entry?.timer) clearTimeout(entry.timer);
44
+ };
45
+ const memo = {
46
+ get(key) {
47
+ const entry = entries.get(key);
48
+ if (!entry) return void 0;
49
+ if (entry.expiresAt !== void 0 && entry.expiresAt <= now()) {
50
+ memo.delete(key);
51
+ return;
52
+ }
53
+ return entry.value;
54
+ },
55
+ set(key, value) {
56
+ clearEntryTimer(entries.get(key));
57
+ const expiresAt = resolveExpiresAt(options.ttlMs, now);
58
+ const entry = {
59
+ value,
60
+ expiresAt
61
+ };
62
+ if (options.scheduleExpiry && expiresAt !== void 0) {
63
+ entry.timer = setTimeout(() => {
64
+ entries.delete(key);
65
+ }, Math.max(0, expiresAt - now()));
66
+ entry.timer.unref?.();
67
+ }
68
+ entries.set(key, entry);
69
+ },
70
+ delete(key) {
71
+ const entry = entries.get(key);
72
+ if (!entry) return false;
73
+ clearEntryTimer(entry);
74
+ return entries.delete(key);
75
+ },
76
+ clear() {
77
+ for (const entry of entries.values()) clearEntryTimer(entry);
78
+ entries.clear();
79
+ }
80
+ };
81
+ processMemoResets.add(memo.clear);
82
+ return memo;
83
+ }
84
+ function resolveExpiresAt(ttlMs, now) {
85
+ if (ttlMs === void 0 || !Number.isFinite(ttlMs)) return void 0;
86
+ return now() + Math.max(0, ttlMs);
87
+ }
88
+ //#endregion
89
+ //#region ../host-kit/src/internal/version.ts
90
+ const versionMemo = createTtlMemo();
91
+ const projectRootMemo = createTtlMemo();
92
+ function readVersion(root = findProjectRoot()) {
93
+ const memoized = versionMemo.get(root);
94
+ if (memoized !== void 0) return memoized;
95
+ let pkg;
96
+ try {
97
+ pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
98
+ } catch {
99
+ return "0.0.0";
100
+ }
101
+ const version = typeof pkg.version === "string" ? pkg.version : "0.0.0";
102
+ versionMemo.set(root, version);
103
+ return version;
104
+ }
105
+ function findProjectRoot() {
106
+ const memoized = projectRootMemo.get("self");
107
+ if (memoized !== void 0) return memoized;
108
+ const resolved = resolveAgentDeviceProjectRoot(path.dirname(fileURLToPath(import.meta.url)));
109
+ projectRootMemo.set("self", resolved);
110
+ return resolved;
111
+ }
112
+ /**
113
+ * Whether `candidate` is a later release than `baseline` (see {@link compareVersions}).
114
+ */
115
+ function isNewerVersion(candidate, baseline) {
116
+ return compareVersions(candidate, baseline) > 0;
117
+ }
118
+ /**
119
+ * SemVer order for the versions this package publishes: numeric `major.minor.patch` first, then a
120
+ * release sorts after any prerelease of the same base (`0.21.13` > `0.21.13-dev`, the shape main
121
+ * carries between releases), and prerelease fields compare per dot-separated field, numerically
122
+ * when both are numbers and lexically otherwise. Build metadata is ignored. A string that is not a
123
+ * version at all reads as `0.0.0`, so a malformed version always compares as the oldest.
124
+ */
125
+ function compareVersions(left, right) {
126
+ const a = parseVersion(left);
127
+ const b = parseVersion(right);
128
+ return compareRelease(a.release, b.release) || comparePrerelease(a.prerelease, b.prerelease);
129
+ }
130
+ const SEMVER = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
131
+ function parseVersion(version) {
132
+ const match = SEMVER.exec(version.trim());
133
+ if (!match) return {
134
+ release: [
135
+ 0,
136
+ 0,
137
+ 0
138
+ ],
139
+ prerelease: []
140
+ };
141
+ return {
142
+ release: [
143
+ Number(match[1]),
144
+ Number(match[2]),
145
+ Number(match[3])
146
+ ],
147
+ prerelease: match[4]?.split(".") ?? []
148
+ };
149
+ }
150
+ function compareRelease(a, b) {
151
+ for (let i = 0; i < 3; i += 1) if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
152
+ return 0;
153
+ }
154
+ /** A release (no prerelease) sorts after every prerelease of the same base. */
155
+ function comparePrerelease(a, b) {
156
+ if (a.length === 0) return b.length === 0 ? 0 : 1;
157
+ if (b.length === 0) return -1;
158
+ const fields = Math.max(a.length, b.length);
159
+ for (let i = 0; i < fields; i += 1) {
160
+ const x = a[i];
161
+ const y = b[i];
162
+ if (x === void 0) return -1;
163
+ if (y === void 0) return 1;
164
+ const order = comparePrereleaseField(x, y);
165
+ if (order !== 0) return order;
166
+ }
167
+ return 0;
168
+ }
169
+ /** Numeric fields compare as numbers and sort below alphanumeric ones; the rest compare lexically. */
170
+ function comparePrereleaseField(x, y) {
171
+ if (x === y) return 0;
172
+ const xNumeric = /^\d+$/.test(x);
173
+ const yNumeric = /^\d+$/.test(y);
174
+ if (xNumeric && yNumeric) return Number(x) > Number(y) ? 1 : -1;
175
+ if (xNumeric !== yNumeric) return xNumeric ? -1 : 1;
176
+ return x > y ? 1 : -1;
177
+ }
178
+ //#endregion
179
+ export { DAEMON_SOURCE_ENTRY, compareVersions, findProjectRoot, isNewerVersion, isSourceCheckoutProjectRoot, readVersion };
package/package.json CHANGED
@@ -1,6 +1,35 @@
1
1
  {
2
2
  "name": "@agent-device/proxy",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.21.23",
4
+ "type": "module",
5
+ "description": "Transport-neutral authenticating proxy in front of an agent-device daemon.",
6
+ "license": "MIT",
7
+ "author": "Callstack",
8
+ "homepage": "https://agent-device.dev/",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/callstack/agent-device.git",
12
+ "directory": "packages/proxy"
13
+ },
14
+ "engines": {
15
+ "node": ">=22.12"
16
+ },
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.mts",
20
+ "import": "./dist/index.mjs"
21
+ },
22
+ "./package.json": "./package.json"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "devDependencies": {
28
+ "@agent-device/contracts": "0.0.0",
29
+ "@agent-device/host-kit": "0.0.0",
30
+ "@agent-device/kernel": "0.0.0"
31
+ },
32
+ "scripts": {
33
+ "build": "tsdown --config tsdown.config.ts"
34
+ }
6
35
  }