@distilled.cloud/fly-io 1.0.0-rc.12 → 1.0.0-rc.14

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 (50) hide show
  1. package/README.md +34 -0
  2. package/lib/credentials.d.ts +2 -2
  3. package/lib/credentials.d.ts.map +1 -1
  4. package/lib/credentials.js +2 -2
  5. package/lib/credentials.js.map +1 -1
  6. package/lib/errors.d.ts.map +1 -1
  7. package/lib/errors.js +1 -1
  8. package/lib/errors.js.map +1 -1
  9. package/lib/protocol.d.ts +4 -4
  10. package/lib/protocol.d.ts.map +1 -1
  11. package/lib/protocol.js +58 -62
  12. package/lib/protocol.js.map +1 -1
  13. package/lib/protocol.test.js +38 -7
  14. package/lib/protocol.test.js.map +1 -1
  15. package/lib/retry.d.ts +1 -1
  16. package/lib/retry.d.ts.map +1 -1
  17. package/lib/retry.js +1 -1
  18. package/lib/retry.js.map +1 -1
  19. package/lib/services/addons.d.ts +58 -8
  20. package/lib/services/addons.d.ts.map +1 -1
  21. package/lib/services/addons.js +40 -85
  22. package/lib/services/addons.js.map +1 -1
  23. package/lib/services/machines.d.ts +209 -60
  24. package/lib/services/machines.d.ts.map +1 -1
  25. package/lib/services/machines.js +316 -692
  26. package/lib/services/machines.js.map +1 -1
  27. package/lib/services/mpg.d.ts +2 -2
  28. package/lib/services/mpg.d.ts.map +1 -1
  29. package/lib/services/mpg.js +37 -153
  30. package/lib/services/mpg.js.map +1 -1
  31. package/lib/services/sprites.d.ts +687 -144
  32. package/lib/services/sprites.d.ts.map +1 -1
  33. package/lib/services/sprites.js +667 -183
  34. package/lib/services/sprites.js.map +1 -1
  35. package/lib/sprites-mint.test.js +4 -5
  36. package/lib/sprites-mint.test.js.map +1 -1
  37. package/lib/traits.d.ts.map +1 -1
  38. package/lib/traits.js.map +1 -1
  39. package/package.json +14 -12
  40. package/src/credentials.ts +8 -12
  41. package/src/errors.ts +6 -10
  42. package/src/protocol.test.ts +83 -43
  43. package/src/protocol.ts +119 -135
  44. package/src/retry.ts +2 -8
  45. package/src/services/addons.ts +135 -154
  46. package/src/services/machines.ts +694 -1222
  47. package/src/services/mpg.ts +59 -217
  48. package/src/services/sprites.ts +1573 -354
  49. package/src/sprites-mint.test.ts +25 -67
  50. package/src/traits.ts +5 -12
@@ -1,14 +1,14 @@
1
- import { describe, expect, test } from "bun:test";
2
1
  import * as API from "@distilled.cloud/core/api";
3
2
  import * as Cause from "effect/Cause";
4
3
  import * as Deferred from "effect/Deferred";
5
4
  import * as Effect from "effect/Effect";
6
5
  import * as Exit from "effect/Exit";
7
6
  import * as Fiber from "effect/Fiber";
7
+ import * as HttpClient from "effect/http/HttpClient";
8
+ import type * as HttpClientRequest from "effect/http/HttpClientRequest";
9
+ import * as HttpClientResponse from "effect/http/HttpClientResponse";
8
10
  import * as Redacted from "effect/Redacted";
9
- import * as HttpClient from "effect/unstable/http/HttpClient";
10
- import type * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
11
- import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
11
+ import { describe, expect, test } from "vitest";
12
12
  import { Credentials } from "./credentials.ts";
13
13
  import { SpritesProtocol } from "./protocol.ts";
14
14
  import { ListSpritesRequest } from "./services/sprites.ts";
@@ -38,8 +38,7 @@ const mintFixture = (apiKey: string) =>
38
38
  }
39
39
  if (
40
40
  request.method !== "POST" ||
41
- request.url !==
42
- "https://api.sprites.dev/v1/organizations/mint-test/tokens"
41
+ request.url !== "https://api.sprites.dev/v1/organizations/mint-test/tokens"
43
42
  ) {
44
43
  return yield* Effect.die("Unexpected test transport request");
45
44
  }
@@ -48,10 +47,7 @@ const mintFixture = (apiKey: string) =>
48
47
  if (!attempt) return yield* Effect.die("Unexpected mint attempt");
49
48
  yield* Deferred.succeed(attempt.started, undefined);
50
49
  const { status, body } = yield* Deferred.await(attempt.response);
51
- return HttpClientResponse.fromWeb(
52
- request,
53
- Response.json(body, { status }),
54
- );
50
+ return HttpClientResponse.fromWeb(request, Response.json(body, { status }));
55
51
  }),
56
52
  );
57
53
  const encode = protocol
@@ -89,9 +85,7 @@ describe("Sprites token mint coordination", () => {
89
85
  Effect.runPromise(
90
86
  Effect.gen(function* () {
91
87
  const fixture = yield* mintFixture("mint-concurrent-fly-secret");
92
- const owner = yield* fixture.encode.pipe(
93
- Effect.forkChild({ startImmediately: true }),
94
- );
88
+ const owner = yield* fixture.encode.pipe(Effect.forkChild({ startImmediately: true }));
95
89
  yield* fixture.started();
96
90
  const waiters = yield* Effect.forEach(Array.from({ length: 20 }), () =>
97
91
  fixture.encode.pipe(Effect.forkChild({ startImmediately: true })),
@@ -104,20 +98,12 @@ describe("Sprites token mint coordination", () => {
104
98
  requests.push(yield* fixture.encode);
105
99
  for (const request of requests) {
106
100
  expect(request.url).toBe("https://api.sprites.dev/v1/sprites");
107
- expect(request.headers.authorization).toBe(
108
- "Bearer mint-concurrent-sprites-secret",
109
- );
110
- expect(JSON.stringify(request)).not.toContain(
111
- "mint-concurrent-sprites-secret",
112
- );
101
+ expect(request.headers.authorization).toBe("Bearer mint-concurrent-sprites-secret");
102
+ expect(JSON.stringify(request)).not.toContain("mint-concurrent-sprites-secret");
113
103
  }
114
- expect(fixture.mints[0]!.headers.authorization).toBe(
115
- "FlyV1 mint-concurrent-fly-secret",
116
- );
104
+ expect(fixture.mints[0]!.headers.authorization).toBe("FlyV1 mint-concurrent-fly-secret");
117
105
  for (const request of [...fixture.discoveries, ...fixture.mints]) {
118
- expect(JSON.stringify(request)).not.toContain(
119
- "mint-concurrent-fly-secret",
120
- );
106
+ expect(JSON.stringify(request)).not.toContain("mint-concurrent-fly-secret");
121
107
  }
122
108
  expect(fixture.credentialReads()).toBe(22);
123
109
  expect(fixture.discoveries).toHaveLength(1);
@@ -129,13 +115,9 @@ describe("Sprites token mint coordination", () => {
129
115
  Effect.runPromise(
130
116
  Effect.gen(function* () {
131
117
  const fixture = yield* mintFixture("mint-retry-fly-secret");
132
- const owner = yield* fixture.encode.pipe(
133
- Effect.forkChild({ startImmediately: true }),
134
- );
118
+ const owner = yield* fixture.encode.pipe(Effect.forkChild({ startImmediately: true }));
135
119
  yield* fixture.started();
136
- const waiter = yield* fixture.encode.pipe(
137
- Effect.forkChild({ startImmediately: true }),
138
- );
120
+ const waiter = yield* fixture.encode.pipe(Effect.forkChild({ startImmediately: true }));
139
121
  expect(fixture.credentialReads()).toBe(2);
140
122
  expect(fixture.mints).toHaveLength(1);
141
123
  yield* fixture.respond({ message: "synthetic mint failure" }, 500);
@@ -143,18 +125,12 @@ describe("Sprites token mint coordination", () => {
143
125
  for (const exit of exits) {
144
126
  expect(Exit.isFailure(exit)).toBe(true);
145
127
  if (Exit.isFailure(exit)) {
146
- expect(Cause.pretty(exit.cause)).toContain(
147
- "synthetic mint failure",
148
- );
149
- expect(Cause.pretty(exit.cause)).not.toContain(
150
- "mint-retry-fly-secret",
151
- );
128
+ expect(Cause.pretty(exit.cause)).toContain("synthetic mint failure");
129
+ expect(Cause.pretty(exit.cause)).not.toContain("mint-retry-fly-secret");
152
130
  }
153
131
  }
154
132
  expect(exits[0]).toEqual(exits[1]);
155
- const retry = yield* fixture.encode.pipe(
156
- Effect.forkChild({ startImmediately: true }),
157
- );
133
+ const retry = yield* fixture.encode.pipe(Effect.forkChild({ startImmediately: true }));
158
134
  yield* fixture.started(1);
159
135
  yield* fixture.respond({ token: "mint-retry-sprites-secret" }, 200, 1);
160
136
  expect((yield* Fiber.join(retry)).headers.authorization).toBe(
@@ -173,20 +149,12 @@ describe("Sprites token mint coordination", () => {
173
149
  Effect.gen(function* () {
174
150
  const first = yield* mintFixture("mint-isolation-first");
175
151
  const second = yield* mintFixture("mint-isolation-second");
176
- const firstFiber = yield* first.encode.pipe(
177
- Effect.forkChild({ startImmediately: true }),
178
- );
179
- const secondFiber = yield* second.encode.pipe(
180
- Effect.forkChild({ startImmediately: true }),
181
- );
152
+ const firstFiber = yield* first.encode.pipe(Effect.forkChild({ startImmediately: true }));
153
+ const secondFiber = yield* second.encode.pipe(Effect.forkChild({ startImmediately: true }));
182
154
  yield* first.started();
183
155
  yield* second.started();
184
- expect(first.mints[0]!.headers.authorization).toBe(
185
- "FlyV1 mint-isolation-first",
186
- );
187
- expect(second.mints[0]!.headers.authorization).toBe(
188
- "FlyV1 mint-isolation-second",
189
- );
156
+ expect(first.mints[0]!.headers.authorization).toBe("FlyV1 mint-isolation-first");
157
+ expect(second.mints[0]!.headers.authorization).toBe("FlyV1 mint-isolation-second");
190
158
  yield* second.respond({ token: "sprites-isolation-second" });
191
159
  expect((yield* Fiber.join(secondFiber)).headers.authorization).toBe(
192
160
  "Bearer sprites-isolation-second",
@@ -195,9 +163,7 @@ describe("Sprites token mint coordination", () => {
195
163
  expect((yield* Fiber.join(firstFiber)).headers.authorization).toBe(
196
164
  "Bearer sprites-isolation-first",
197
165
  );
198
- expect((yield* first.encode).headers.authorization).toBe(
199
- "Bearer sprites-isolation-first",
200
- );
166
+ expect((yield* first.encode).headers.authorization).toBe("Bearer sprites-isolation-first");
201
167
  expect((yield* second.encode).headers.authorization).toBe(
202
168
  "Bearer sprites-isolation-second",
203
169
  );
@@ -210,13 +176,9 @@ describe("Sprites token mint coordination", () => {
210
176
  Effect.runPromise(
211
177
  Effect.gen(function* () {
212
178
  const fixture = yield* mintFixture("mint-interrupted-waiter");
213
- const owner = yield* fixture.encode.pipe(
214
- Effect.forkChild({ startImmediately: true }),
215
- );
179
+ const owner = yield* fixture.encode.pipe(Effect.forkChild({ startImmediately: true }));
216
180
  yield* fixture.started();
217
- const waiter = yield* fixture.encode.pipe(
218
- Effect.forkChild({ startImmediately: true }),
219
- );
181
+ const waiter = yield* fixture.encode.pipe(Effect.forkChild({ startImmediately: true }));
220
182
  expect(fixture.credentialReads()).toBe(2);
221
183
  yield* Fiber.interrupt(waiter);
222
184
  expect(Exit.hasInterrupts(yield* Fiber.await(waiter))).toBe(true);
@@ -239,9 +201,7 @@ describe("Sprites token mint coordination", () => {
239
201
  Effect.runPromise(
240
202
  Effect.gen(function* () {
241
203
  const fixture = yield* mintFixture("mint-interrupted-owner");
242
- const owner = yield* fixture.encode.pipe(
243
- Effect.forkChild({ startImmediately: true }),
244
- );
204
+ const owner = yield* fixture.encode.pipe(Effect.forkChild({ startImmediately: true }));
245
205
  yield* fixture.started();
246
206
  const waiters = yield* Effect.forEach([0, 1, 2], () =>
247
207
  fixture.encode.pipe(Effect.forkChild({ startImmediately: true })),
@@ -252,9 +212,7 @@ describe("Sprites token mint coordination", () => {
252
212
  for (const exit of yield* Fiber.awaitAll([owner, ...waiters])) {
253
213
  expect(Exit.hasInterrupts(exit)).toBe(true);
254
214
  }
255
- const retry = yield* fixture.encode.pipe(
256
- Effect.forkChild({ startImmediately: true }),
257
- );
215
+ const retry = yield* fixture.encode.pipe(Effect.forkChild({ startImmediately: true }));
258
216
  yield* fixture.started(1);
259
217
  yield* fixture.respond({ token: "sprites-after-interruption" }, 200, 1);
260
218
  expect((yield* Fiber.join(retry)).headers.authorization).toBe(
package/src/traits.ts CHANGED
@@ -58,21 +58,14 @@ export interface GraphQLOpTrait {
58
58
  export const graphqlOpSymbol = Symbol.for("@distilled.cloud/fly-io/graphql-op");
59
59
 
60
60
  /** Marks an operation input with its GraphQL document (`com.flyio.graphql#operation`). */
61
- export const GraphQLOp = (op: GraphQLOpTrait) =>
62
- makeAnnotation(graphqlOpSymbol, op);
61
+ export const GraphQLOp = (op: GraphQLOpTrait) => makeAnnotation(graphqlOpSymbol, op);
63
62
 
64
- export const responsePathSymbol = Symbol.for(
65
- "@distilled.cloud/fly-io/graphql-response-path",
66
- );
63
+ export const responsePathSymbol = Symbol.for("@distilled.cloud/fly-io/graphql-response-path");
67
64
 
68
65
  /** Dotted path under GraphQL `data` (`com.flyio.graphql#responsePath`). */
69
- export const ResponsePath = (path: string) =>
70
- makeAnnotation(responsePathSymbol, path);
66
+ export const ResponsePath = (path: string) => makeAnnotation(responsePathSymbol, path);
71
67
 
72
- export const graphqlPayloadRootSymbol = Symbol.for(
73
- "@distilled.cloud/fly-io/graphql-payload-root",
74
- );
68
+ export const graphqlPayloadRootSymbol = Symbol.for("@distilled.cloud/fly-io/graphql-payload-root");
75
69
 
76
70
  /** Marks a response whose entire value is `data.<responsePath>`. */
77
- export const GraphQLPayloadRoot = () =>
78
- makeAnnotation(graphqlPayloadRootSymbol, true);
71
+ export const GraphQLPayloadRoot = () => makeAnnotation(graphqlPayloadRootSymbol, true);