@limrun/api 0.46.1 → 0.46.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/index.d.mts +2 -1
  3. package/index.d.mts.map +1 -1
  4. package/index.d.ts +2 -1
  5. package/index.d.ts.map +1 -1
  6. package/index.js +10 -1
  7. package/index.js.map +1 -1
  8. package/index.mjs +1 -0
  9. package/index.mjs.map +1 -1
  10. package/ios-client.d.mts.map +1 -1
  11. package/ios-client.d.ts.map +1 -1
  12. package/ios-client.js +3 -1
  13. package/ios-client.js.map +1 -1
  14. package/ios-client.mjs +3 -1
  15. package/ios-client.mjs.map +1 -1
  16. package/package.json +11 -1
  17. package/resources/assets-helpers.d.mts.map +1 -1
  18. package/resources/assets-helpers.d.ts.map +1 -1
  19. package/resources/assets-helpers.js +9 -4
  20. package/resources/assets-helpers.js.map +1 -1
  21. package/resources/assets-helpers.mjs +9 -4
  22. package/resources/assets-helpers.mjs.map +1 -1
  23. package/resources/gradle-instances.d.mts +9 -0
  24. package/resources/gradle-instances.d.mts.map +1 -1
  25. package/resources/gradle-instances.d.ts +9 -0
  26. package/resources/gradle-instances.d.ts.map +1 -1
  27. package/resources/index.d.mts +1 -1
  28. package/resources/index.d.mts.map +1 -1
  29. package/resources/index.d.ts +1 -1
  30. package/resources/index.d.ts.map +1 -1
  31. package/resources/index.js.map +1 -1
  32. package/resources/index.mjs.map +1 -1
  33. package/resources/xcode-instances-helpers.d.mts +30 -1
  34. package/resources/xcode-instances-helpers.d.mts.map +1 -1
  35. package/resources/xcode-instances-helpers.d.ts +30 -1
  36. package/resources/xcode-instances-helpers.d.ts.map +1 -1
  37. package/resources/xcode-instances-helpers.js +38 -0
  38. package/resources/xcode-instances-helpers.js.map +1 -1
  39. package/resources/xcode-instances-helpers.mjs +39 -1
  40. package/resources/xcode-instances-helpers.mjs.map +1 -1
  41. package/src/index.ts +21 -0
  42. package/src/ios-client.ts +3 -1
  43. package/src/resources/assets-helpers.ts +9 -4
  44. package/src/resources/gradle-instances.ts +10 -0
  45. package/src/resources/index.ts +1 -0
  46. package/src/resources/xcode-instances-helpers.ts +61 -1
  47. package/src/version.ts +1 -1
  48. package/src/xcode-cache.ts +327 -0
  49. package/version.d.mts +1 -1
  50. package/version.d.ts +1 -1
  51. package/version.js +1 -1
  52. package/version.mjs +1 -1
  53. package/xcode-cache.d.mts +142 -0
  54. package/xcode-cache.d.mts.map +1 -0
  55. package/xcode-cache.d.ts +142 -0
  56. package/xcode-cache.d.ts.map +1 -0
  57. package/xcode-cache.js +175 -0
  58. package/xcode-cache.js.map +1 -0
  59. package/xcode-cache.mjs +165 -0
  60. package/xcode-cache.mjs.map +1 -0
package/xcode-cache.js ADDED
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.XcodeCacheTimeoutError = exports.XcodeCacheGoneError = void 0;
4
+ exports.isRestoreTerminal = isRestoreTerminal;
5
+ exports.isRestoreFailure = isRestoreFailure;
6
+ exports.isSaveTerminal = isSaveTerminal;
7
+ exports.isCacheTerminal = isCacheTerminal;
8
+ exports.followXcodeCache = followXcodeCache;
9
+ const eventsource_client_1 = require("eventsource-client");
10
+ const proxy_transport_1 = require("./internal/proxy-transport.js");
11
+ /**
12
+ * The instance was gone before it said anything about its cache, so there is no last state to
13
+ * summarise. Distinct from a follow that ends with `gone: true`, which at least saw one.
14
+ */
15
+ class XcodeCacheGoneError extends Error {
16
+ constructor(instanceId) {
17
+ super(`Instance ${instanceId} was gone before it reported any cache status`);
18
+ this.instanceId = instanceId;
19
+ this.name = 'XcodeCacheGoneError';
20
+ }
21
+ }
22
+ exports.XcodeCacheGoneError = XcodeCacheGoneError;
23
+ class XcodeCacheTimeoutError extends Error {
24
+ constructor(side, timeoutMs, cache) {
25
+ super(`Timed out after ${Math.round(timeoutMs / 1000)}s waiting for the cache ${side} to finish` +
26
+ (cache ? ` (last phase: ${cache[side].phase})` : ''));
27
+ this.side = side;
28
+ this.timeoutMs = timeoutMs;
29
+ this.cache = cache;
30
+ this.name = 'XcodeCacheTimeoutError';
31
+ }
32
+ }
33
+ exports.XcodeCacheTimeoutError = XcodeCacheTimeoutError;
34
+ const DEFAULT_TIMEOUT_MS = {
35
+ restore: 20 * 60 * 1000,
36
+ save: 12 * 60 * 1000,
37
+ };
38
+ /** Phases past which nothing more will happen. */
39
+ function isRestoreTerminal(phase) {
40
+ return (phase === 'disabled' ||
41
+ phase === 'unsupported' ||
42
+ phase === 'restored' ||
43
+ phase === 'skipped' ||
44
+ phase === 'failed');
45
+ }
46
+ /**
47
+ * Separates the one outcome worth reacting to from the terminal phases that just mean "cold,
48
+ * carry on". A caller that created an instance for a warm workspace deletes it on a failure,
49
+ * but a fallback to a cold build leaves a perfectly usable instance behind.
50
+ */
51
+ function isRestoreFailure(phase) {
52
+ return phase === 'failed';
53
+ }
54
+ function isSaveTerminal(phase) {
55
+ return (phase === 'disabled' ||
56
+ phase === 'published' ||
57
+ phase === 'skipped' ||
58
+ phase === 'failed' ||
59
+ phase === 'timed_out');
60
+ }
61
+ function isCacheTerminal(cache, side) {
62
+ return side === 'restore' ? isRestoreTerminal(cache.restore.phase) : isSaveTerminal(cache.save.phase);
63
+ }
64
+ /**
65
+ * Follows an instance's cache status until the chosen side reaches a terminal phase, the
66
+ * instance is collected, or the wait times out.
67
+ *
68
+ * The transport is the same endpoint that serves a JSON snapshot, asked for as an event
69
+ * stream. The server emits on phase change only, so every callback is a real transition.
70
+ */
71
+ function followXcodeCache(target, options = {}) {
72
+ const side = options.side ?? 'restore';
73
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS[side];
74
+ let base = target.baseURL;
75
+ while (base.endsWith('/'))
76
+ base = base.slice(0, -1);
77
+ const url = `${base}/v1/xcode_instances/${encodeURIComponent(target.instanceId)}/cache`;
78
+ return new Promise((resolve, reject) => {
79
+ let last;
80
+ let lastKey = '';
81
+ let settled = false;
82
+ const finish = (fn) => {
83
+ if (settled)
84
+ return;
85
+ settled = true;
86
+ clearTimeout(timer);
87
+ options.signal?.removeEventListener('abort', onAbort);
88
+ try {
89
+ source.close();
90
+ }
91
+ catch {
92
+ // A stream that never opened has nothing to close.
93
+ }
94
+ fn();
95
+ };
96
+ const timer = setTimeout(() => finish(() => reject(new XcodeCacheTimeoutError(side, timeoutMs, last))), timeoutMs);
97
+ const onAbort = () => finish(() => reject(options.signal?.reason ?? new Error('aborted')));
98
+ let confirming = false;
99
+ const confirmGone = () => {
100
+ if (confirming || settled)
101
+ return;
102
+ confirming = true;
103
+ proxy_transport_1.nodeProxyTransport
104
+ .fetch(url, {
105
+ headers: { Authorization: `Bearer ${target.apiKey}`, Accept: 'application/json' },
106
+ })
107
+ .then(async (res) => {
108
+ confirming = false;
109
+ if (res.status !== 404) {
110
+ await res.text().catch(() => undefined);
111
+ return;
112
+ }
113
+ finish(() => last ? resolve({ cache: last, gone: true }) : reject(new XcodeCacheGoneError(target.instanceId)));
114
+ })
115
+ .catch(() => {
116
+ confirming = false;
117
+ });
118
+ };
119
+ // The endpoint answers from the region, which keeps the instance while it terminates and
120
+ // drops it once it is collected, so a 404 is the instance being over rather than a fault.
121
+ // Without this the client treats it as a connection to retry and follows a gone instance
122
+ // until the timeout, which is minutes of a command that looks hung and says nothing.
123
+ const fetchOrGone = async (input, init) => {
124
+ const res = await proxy_transport_1.nodeProxyTransport.fetch(input, init);
125
+ if (res.status === 404) {
126
+ finish(() => last ? resolve({ cache: last, gone: true }) : reject(new XcodeCacheGoneError(target.instanceId)));
127
+ }
128
+ return res;
129
+ };
130
+ const source = (0, eventsource_client_1.createEventSource)({
131
+ url,
132
+ fetch: fetchOrGone,
133
+ onConnect: () => options.onOpen?.(),
134
+ headers: {
135
+ Authorization: `Bearer ${target.apiKey}`,
136
+ Accept: 'text/event-stream',
137
+ },
138
+ onMessage: (message) => {
139
+ if (message.event !== 'cache' && message.event !== 'gone')
140
+ return;
141
+ let cache;
142
+ try {
143
+ cache = JSON.parse(typeof message.data === 'string' ? message.data : String(message.data));
144
+ }
145
+ catch (err) {
146
+ finish(() => reject(new Error(`Cache stream sent unreadable data: ${err}`)));
147
+ return;
148
+ }
149
+ last = cache;
150
+ if (message.event === 'gone') {
151
+ // The server also ends the stream this way when its own watch is cut short, which
152
+ // Kubernetes does routinely on a long one, so a snapshot decides which it was. The
153
+ // client library reconnects on its own when the instance is in fact still there.
154
+ confirmGone();
155
+ return;
156
+ }
157
+ // A reconnect replays the current state, which is not a transition.
158
+ const key = `${cache.restore.phase}/${cache.restore.reason ?? ''}|${cache.save.phase}/${cache.save.reason ?? ''}`;
159
+ if (key !== lastKey) {
160
+ lastKey = key;
161
+ options.onUpdate?.(cache);
162
+ }
163
+ if (isCacheTerminal(cache, side)) {
164
+ finish(() => resolve({ cache, gone: false }));
165
+ }
166
+ },
167
+ });
168
+ if (options.signal?.aborted) {
169
+ onAbort();
170
+ return;
171
+ }
172
+ options.signal?.addEventListener('abort', onAbort, { once: true });
173
+ });
174
+ }
175
+ //# sourceMappingURL=xcode-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xcode-cache.js","sourceRoot":"","sources":["src/xcode-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,165 @@
1
+ import { createEventSource } from 'eventsource-client';
2
+ import { nodeProxyTransport } from "./internal/proxy-transport.mjs";
3
+ /**
4
+ * The instance was gone before it said anything about its cache, so there is no last state to
5
+ * summarise. Distinct from a follow that ends with `gone: true`, which at least saw one.
6
+ */
7
+ export class XcodeCacheGoneError extends Error {
8
+ constructor(instanceId) {
9
+ super(`Instance ${instanceId} was gone before it reported any cache status`);
10
+ this.instanceId = instanceId;
11
+ this.name = 'XcodeCacheGoneError';
12
+ }
13
+ }
14
+ export class XcodeCacheTimeoutError extends Error {
15
+ constructor(side, timeoutMs, cache) {
16
+ super(`Timed out after ${Math.round(timeoutMs / 1000)}s waiting for the cache ${side} to finish` +
17
+ (cache ? ` (last phase: ${cache[side].phase})` : ''));
18
+ this.side = side;
19
+ this.timeoutMs = timeoutMs;
20
+ this.cache = cache;
21
+ this.name = 'XcodeCacheTimeoutError';
22
+ }
23
+ }
24
+ const DEFAULT_TIMEOUT_MS = {
25
+ restore: 20 * 60 * 1000,
26
+ save: 12 * 60 * 1000,
27
+ };
28
+ /** Phases past which nothing more will happen. */
29
+ export function isRestoreTerminal(phase) {
30
+ return (phase === 'disabled' ||
31
+ phase === 'unsupported' ||
32
+ phase === 'restored' ||
33
+ phase === 'skipped' ||
34
+ phase === 'failed');
35
+ }
36
+ /**
37
+ * Separates the one outcome worth reacting to from the terminal phases that just mean "cold,
38
+ * carry on". A caller that created an instance for a warm workspace deletes it on a failure,
39
+ * but a fallback to a cold build leaves a perfectly usable instance behind.
40
+ */
41
+ export function isRestoreFailure(phase) {
42
+ return phase === 'failed';
43
+ }
44
+ export function isSaveTerminal(phase) {
45
+ return (phase === 'disabled' ||
46
+ phase === 'published' ||
47
+ phase === 'skipped' ||
48
+ phase === 'failed' ||
49
+ phase === 'timed_out');
50
+ }
51
+ export function isCacheTerminal(cache, side) {
52
+ return side === 'restore' ? isRestoreTerminal(cache.restore.phase) : isSaveTerminal(cache.save.phase);
53
+ }
54
+ /**
55
+ * Follows an instance's cache status until the chosen side reaches a terminal phase, the
56
+ * instance is collected, or the wait times out.
57
+ *
58
+ * The transport is the same endpoint that serves a JSON snapshot, asked for as an event
59
+ * stream. The server emits on phase change only, so every callback is a real transition.
60
+ */
61
+ export function followXcodeCache(target, options = {}) {
62
+ const side = options.side ?? 'restore';
63
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS[side];
64
+ let base = target.baseURL;
65
+ while (base.endsWith('/'))
66
+ base = base.slice(0, -1);
67
+ const url = `${base}/v1/xcode_instances/${encodeURIComponent(target.instanceId)}/cache`;
68
+ return new Promise((resolve, reject) => {
69
+ let last;
70
+ let lastKey = '';
71
+ let settled = false;
72
+ const finish = (fn) => {
73
+ if (settled)
74
+ return;
75
+ settled = true;
76
+ clearTimeout(timer);
77
+ options.signal?.removeEventListener('abort', onAbort);
78
+ try {
79
+ source.close();
80
+ }
81
+ catch {
82
+ // A stream that never opened has nothing to close.
83
+ }
84
+ fn();
85
+ };
86
+ const timer = setTimeout(() => finish(() => reject(new XcodeCacheTimeoutError(side, timeoutMs, last))), timeoutMs);
87
+ const onAbort = () => finish(() => reject(options.signal?.reason ?? new Error('aborted')));
88
+ let confirming = false;
89
+ const confirmGone = () => {
90
+ if (confirming || settled)
91
+ return;
92
+ confirming = true;
93
+ nodeProxyTransport
94
+ .fetch(url, {
95
+ headers: { Authorization: `Bearer ${target.apiKey}`, Accept: 'application/json' },
96
+ })
97
+ .then(async (res) => {
98
+ confirming = false;
99
+ if (res.status !== 404) {
100
+ await res.text().catch(() => undefined);
101
+ return;
102
+ }
103
+ finish(() => last ? resolve({ cache: last, gone: true }) : reject(new XcodeCacheGoneError(target.instanceId)));
104
+ })
105
+ .catch(() => {
106
+ confirming = false;
107
+ });
108
+ };
109
+ // The endpoint answers from the region, which keeps the instance while it terminates and
110
+ // drops it once it is collected, so a 404 is the instance being over rather than a fault.
111
+ // Without this the client treats it as a connection to retry and follows a gone instance
112
+ // until the timeout, which is minutes of a command that looks hung and says nothing.
113
+ const fetchOrGone = async (input, init) => {
114
+ const res = await nodeProxyTransport.fetch(input, init);
115
+ if (res.status === 404) {
116
+ finish(() => last ? resolve({ cache: last, gone: true }) : reject(new XcodeCacheGoneError(target.instanceId)));
117
+ }
118
+ return res;
119
+ };
120
+ const source = createEventSource({
121
+ url,
122
+ fetch: fetchOrGone,
123
+ onConnect: () => options.onOpen?.(),
124
+ headers: {
125
+ Authorization: `Bearer ${target.apiKey}`,
126
+ Accept: 'text/event-stream',
127
+ },
128
+ onMessage: (message) => {
129
+ if (message.event !== 'cache' && message.event !== 'gone')
130
+ return;
131
+ let cache;
132
+ try {
133
+ cache = JSON.parse(typeof message.data === 'string' ? message.data : String(message.data));
134
+ }
135
+ catch (err) {
136
+ finish(() => reject(new Error(`Cache stream sent unreadable data: ${err}`)));
137
+ return;
138
+ }
139
+ last = cache;
140
+ if (message.event === 'gone') {
141
+ // The server also ends the stream this way when its own watch is cut short, which
142
+ // Kubernetes does routinely on a long one, so a snapshot decides which it was. The
143
+ // client library reconnects on its own when the instance is in fact still there.
144
+ confirmGone();
145
+ return;
146
+ }
147
+ // A reconnect replays the current state, which is not a transition.
148
+ const key = `${cache.restore.phase}/${cache.restore.reason ?? ''}|${cache.save.phase}/${cache.save.reason ?? ''}`;
149
+ if (key !== lastKey) {
150
+ lastKey = key;
151
+ options.onUpdate?.(cache);
152
+ }
153
+ if (isCacheTerminal(cache, side)) {
154
+ finish(() => resolve({ cache, gone: false }));
155
+ }
156
+ },
157
+ });
158
+ if (options.signal?.aborted) {
159
+ onAbort();
160
+ return;
161
+ }
162
+ options.signal?.addEventListener('abort', onAbort, { once: true });
163
+ });
164
+ }
165
+ //# sourceMappingURL=xcode-cache.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xcode-cache.mjs","sourceRoot":"","sources":["src/xcode-cache.ts"],"names":[],"mappings":"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"}