@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.
- package/README.md +34 -0
- package/lib/credentials.d.ts +2 -2
- package/lib/credentials.d.ts.map +1 -1
- package/lib/credentials.js +2 -2
- package/lib/credentials.js.map +1 -1
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +1 -1
- package/lib/errors.js.map +1 -1
- package/lib/protocol.d.ts +4 -4
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +58 -62
- package/lib/protocol.js.map +1 -1
- package/lib/protocol.test.js +38 -7
- package/lib/protocol.test.js.map +1 -1
- package/lib/retry.d.ts +1 -1
- package/lib/retry.d.ts.map +1 -1
- package/lib/retry.js +1 -1
- package/lib/retry.js.map +1 -1
- package/lib/services/addons.d.ts +58 -8
- package/lib/services/addons.d.ts.map +1 -1
- package/lib/services/addons.js +40 -85
- package/lib/services/addons.js.map +1 -1
- package/lib/services/machines.d.ts +209 -60
- package/lib/services/machines.d.ts.map +1 -1
- package/lib/services/machines.js +316 -692
- package/lib/services/machines.js.map +1 -1
- package/lib/services/mpg.d.ts +2 -2
- package/lib/services/mpg.d.ts.map +1 -1
- package/lib/services/mpg.js +37 -153
- package/lib/services/mpg.js.map +1 -1
- package/lib/services/sprites.d.ts +687 -144
- package/lib/services/sprites.d.ts.map +1 -1
- package/lib/services/sprites.js +667 -183
- package/lib/services/sprites.js.map +1 -1
- package/lib/sprites-mint.test.js +4 -5
- package/lib/sprites-mint.test.js.map +1 -1
- package/lib/traits.d.ts.map +1 -1
- package/lib/traits.js.map +1 -1
- package/package.json +14 -12
- package/src/credentials.ts +8 -12
- package/src/errors.ts +6 -10
- package/src/protocol.test.ts +83 -43
- package/src/protocol.ts +119 -135
- package/src/retry.ts +2 -8
- package/src/services/addons.ts +135 -154
- package/src/services/machines.ts +694 -1222
- package/src/services/mpg.ts +59 -217
- package/src/services/sprites.ts +1573 -354
- package/src/sprites-mint.test.ts +25 -67
- package/src/traits.ts +5 -12
package/src/sprites-mint.test.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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);
|