@useairfoil/flight 0.3.0 → 0.4.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.
@@ -1,30 +0,0 @@
1
- import { StartedTestContainer } from "testcontainers";
2
- import { Effect, Layer } from "effect";
3
- import * as ServiceMap from "effect/ServiceMap";
4
-
5
- //#region test/wings-container.d.ts
6
- declare class WingsContainer {
7
- private container;
8
- start(): Promise<WingsContainer>;
9
- stop(): Promise<void>;
10
- getGrpcPort(): number;
11
- getHttpPort(): number;
12
- getGrpcHost(): string;
13
- getHttpHost(): string;
14
- private getHost;
15
- getContainer(): StartedTestContainer;
16
- }
17
- //#endregion
18
- //#region test/wings-container.effect.d.ts
19
- declare const EffectWingsContainer_base: ServiceMap.ServiceClass<EffectWingsContainer, "EffectWingsContainer", {
20
- readonly getGrpcPort: Effect.Effect<number>;
21
- readonly getHttpPort: Effect.Effect<number>;
22
- readonly getGrpcHost: Effect.Effect<string>;
23
- readonly getHttpHost: Effect.Effect<string>;
24
- readonly getContainer: Effect.Effect<StartedTestContainer>;
25
- }>;
26
- declare class EffectWingsContainer extends EffectWingsContainer_base {}
27
- declare const EffectWingsContainerLive: Layer.Layer<EffectWingsContainer, Error, never>;
28
- //#endregion
29
- export { EffectWingsContainer, EffectWingsContainerLive, WingsContainer };
30
- //# sourceMappingURL=index.d.ts.map
@@ -1,80 +0,0 @@
1
- import { GenericContainer, Wait } from "testcontainers";
2
- import { Effect, Layer, Scope } from "effect";
3
- import * as ServiceMap from "effect/ServiceMap";
4
-
5
- //#region test/wings-container.ts
6
- var WingsContainer = class {
7
- container = null;
8
- async start() {
9
- this.container = await new GenericContainer("docker.useairfoil.com/airfoil/wings:latest").withCommand([
10
- "dev",
11
- "--http.address=0.0.0.0:7780",
12
- "--metadata.address=0.0.0.0:7777"
13
- ]).withExposedPorts(7777, 7780).withTmpFs({ "/tmp": "rw" }).withWaitStrategy(Wait.forLogMessage(/gRPC server listening on 0\.0\.0\.0:7777/)).withStartupTimeout(6e4).start();
14
- return this;
15
- }
16
- async stop() {
17
- if (this.container) {
18
- await this.container.stop();
19
- this.container = null;
20
- }
21
- }
22
- getGrpcPort() {
23
- if (!this.container) throw new Error("Container not started");
24
- return this.container.getMappedPort(7777);
25
- }
26
- getHttpPort() {
27
- if (!this.container) throw new Error("Container not started");
28
- return this.container.getMappedPort(7780);
29
- }
30
- getGrpcHost() {
31
- return `${this.getHost()}:${this.getGrpcPort()}`;
32
- }
33
- getHttpHost() {
34
- return `${this.getHost()}:${this.getHttpPort()}`;
35
- }
36
- getHost() {
37
- if (!this.container) throw new Error("Container not started");
38
- return this.container.getHost();
39
- }
40
- getContainer() {
41
- if (!this.container) throw new Error("Container not started");
42
- return this.container;
43
- }
44
- };
45
-
46
- //#endregion
47
- //#region test/wings-container.effect.ts
48
- var EffectWingsContainer = class extends ServiceMap.Service()("EffectWingsContainer") {};
49
- const EffectWingsContainerLive = Layer.effect(EffectWingsContainer)(Effect.gen(function* () {
50
- const scope = yield* Scope.Scope;
51
- const container = yield* Effect.tryPromise({
52
- try: () => new GenericContainer("docker.useairfoil.com/airfoil/wings:latest").withCommand([
53
- "dev",
54
- "--http.address=0.0.0.0:7780",
55
- "--metadata.address=0.0.0.0:7777"
56
- ]).withExposedPorts(7777, 7780).withTmpFs({ "/tmp": "rw" }).withWaitStrategy(Wait.forLogMessage(/gRPC server listening on 0\.0\.0\.0:7777/)).withStartupTimeout(6e4).start(),
57
- catch: (error) => /* @__PURE__ */ new Error(`Failed to start container: ${error}`)
58
- });
59
- yield* Scope.addFinalizer(scope, Effect.tryPromise({
60
- try: () => container.stop(),
61
- catch: (error) => /* @__PURE__ */ new Error(`Failed to stop container: ${error}`)
62
- }).pipe(Effect.tap(() => Effect.log("Container stopped successfully")), Effect.catch((error) => Effect.log(`Error stopping container: ${error}`))));
63
- return {
64
- getGrpcPort: Effect.sync(() => container.getMappedPort(7777)),
65
- getHttpPort: Effect.sync(() => container.getMappedPort(7780)),
66
- getGrpcHost: Effect.gen(function* () {
67
- const port = yield* Effect.sync(() => container.getMappedPort(7777));
68
- return `${yield* Effect.sync(() => container.getHost())}:${port}`;
69
- }),
70
- getHttpHost: Effect.gen(function* () {
71
- const port = yield* Effect.sync(() => container.getMappedPort(7780));
72
- return `${yield* Effect.sync(() => container.getHost())}:${port}`;
73
- }),
74
- getContainer: Effect.succeed(container)
75
- };
76
- }));
77
-
78
- //#endregion
79
- export { EffectWingsContainer, EffectWingsContainerLive, WingsContainer };
80
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../test/wings-container.ts","../../test/wings-container.effect.ts"],"sourcesContent":["import {\n GenericContainer,\n type StartedTestContainer,\n Wait,\n} from \"testcontainers\";\n\nexport class WingsContainer {\n private container: StartedTestContainer | null = null;\n\n async start(): Promise<WingsContainer> {\n const container = new GenericContainer(\n \"docker.useairfoil.com/airfoil/wings:latest\",\n )\n .withCommand([\n \"dev\",\n \"--http.address=0.0.0.0:7780\",\n \"--metadata.address=0.0.0.0:7777\",\n ])\n .withExposedPorts(7777, 7780)\n .withTmpFs({ \"/tmp\": \"rw\" })\n .withWaitStrategy(\n Wait.forLogMessage(/gRPC server listening on 0\\.0\\.0\\.0:7777/),\n )\n .withStartupTimeout(60_000);\n\n this.container = await container.start();\n return this;\n }\n\n async stop(): Promise<void> {\n if (this.container) {\n await this.container.stop();\n this.container = null;\n }\n }\n\n getGrpcPort(): number {\n if (!this.container) {\n throw new Error(\"Container not started\");\n }\n return this.container.getMappedPort(7777);\n }\n\n getHttpPort(): number {\n if (!this.container) {\n throw new Error(\"Container not started\");\n }\n return this.container.getMappedPort(7780);\n }\n\n getGrpcHost(): string {\n return `${this.getHost()}:${this.getGrpcPort()}`;\n }\n\n getHttpHost(): string {\n return `${this.getHost()}:${this.getHttpPort()}`;\n }\n\n private getHost(): string {\n if (!this.container) {\n throw new Error(\"Container not started\");\n }\n return this.container.getHost();\n }\n\n getContainer(): StartedTestContainer {\n if (!this.container) {\n throw new Error(\"Container not started\");\n }\n return this.container;\n }\n}\n","import { Effect, Layer, Scope } from \"effect\";\nimport * as ServiceMap from \"effect/ServiceMap\";\nimport {\n GenericContainer,\n type StartedTestContainer,\n Wait,\n} from \"testcontainers\";\n\nexport class EffectWingsContainer extends ServiceMap.Service<\n EffectWingsContainer,\n {\n readonly getGrpcPort: Effect.Effect<number>;\n readonly getHttpPort: Effect.Effect<number>;\n readonly getGrpcHost: Effect.Effect<string>;\n readonly getHttpHost: Effect.Effect<string>;\n readonly getContainer: Effect.Effect<StartedTestContainer>;\n }\n>()(\"EffectWingsContainer\") {}\n\nexport const EffectWingsContainerLive = Layer.effect(EffectWingsContainer)(\n Effect.gen(function* () {\n const scope = yield* Scope.Scope;\n\n const container = yield* Effect.tryPromise({\n try: () =>\n new GenericContainer(\"docker.useairfoil.com/airfoil/wings:latest\")\n .withCommand([\n \"dev\",\n \"--http.address=0.0.0.0:7780\",\n \"--metadata.address=0.0.0.0:7777\",\n ])\n .withExposedPorts(7777, 7780)\n .withTmpFs({ \"/tmp\": \"rw\" })\n .withWaitStrategy(\n Wait.forLogMessage(/gRPC server listening on 0\\.0\\.0\\.0:7777/),\n )\n .withStartupTimeout(60_000)\n .start(),\n catch: (error) => new Error(`Failed to start container: ${error}`),\n });\n\n yield* Scope.addFinalizer(\n scope,\n Effect.tryPromise({\n try: () => container.stop(),\n catch: (error) => new Error(`Failed to stop container: ${error}`),\n }).pipe(\n Effect.tap(() => Effect.log(\"Container stopped successfully\")),\n Effect.catch((error) =>\n Effect.log(`Error stopping container: ${error}`),\n ),\n ),\n );\n\n return {\n getGrpcPort: Effect.sync(() => container.getMappedPort(7777)),\n getHttpPort: Effect.sync(() => container.getMappedPort(7780)),\n getGrpcHost: Effect.gen(function* () {\n const port = yield* Effect.sync(() => container.getMappedPort(7777));\n const host = yield* Effect.sync(() => container.getHost());\n return `${host}:${port}`;\n }),\n getHttpHost: Effect.gen(function* () {\n const port = yield* Effect.sync(() => container.getMappedPort(7780));\n const host = yield* Effect.sync(() => container.getHost());\n return `${host}:${port}`;\n }),\n getContainer: Effect.succeed(container),\n };\n }),\n);\n"],"mappings":";;;;;AAMA,IAAa,iBAAb,MAA4B;CAC1B,AAAQ,YAAyC;CAEjD,MAAM,QAAiC;AAgBrC,OAAK,YAAY,MAfC,IAAI,iBACpB,6CACD,CACE,YAAY;GACX;GACA;GACA;GACD,CAAC,CACD,iBAAiB,MAAM,KAAK,CAC5B,UAAU,EAAE,QAAQ,MAAM,CAAC,CAC3B,iBACC,KAAK,cAAc,2CAA2C,CAC/D,CACA,mBAAmB,IAAO,CAEI,OAAO;AACxC,SAAO;;CAGT,MAAM,OAAsB;AAC1B,MAAI,KAAK,WAAW;AAClB,SAAM,KAAK,UAAU,MAAM;AAC3B,QAAK,YAAY;;;CAIrB,cAAsB;AACpB,MAAI,CAAC,KAAK,UACR,OAAM,IAAI,MAAM,wBAAwB;AAE1C,SAAO,KAAK,UAAU,cAAc,KAAK;;CAG3C,cAAsB;AACpB,MAAI,CAAC,KAAK,UACR,OAAM,IAAI,MAAM,wBAAwB;AAE1C,SAAO,KAAK,UAAU,cAAc,KAAK;;CAG3C,cAAsB;AACpB,SAAO,GAAG,KAAK,SAAS,CAAC,GAAG,KAAK,aAAa;;CAGhD,cAAsB;AACpB,SAAO,GAAG,KAAK,SAAS,CAAC,GAAG,KAAK,aAAa;;CAGhD,AAAQ,UAAkB;AACxB,MAAI,CAAC,KAAK,UACR,OAAM,IAAI,MAAM,wBAAwB;AAE1C,SAAO,KAAK,UAAU,SAAS;;CAGjC,eAAqC;AACnC,MAAI,CAAC,KAAK,UACR,OAAM,IAAI,MAAM,wBAAwB;AAE1C,SAAO,KAAK;;;;;;AC7DhB,IAAa,uBAAb,cAA0C,WAAW,SASlD,CAAC,uBAAuB,CAAC;AAE5B,MAAa,2BAA2B,MAAM,OAAO,qBAAqB,CACxE,OAAO,IAAI,aAAa;CACtB,MAAM,QAAQ,OAAO,MAAM;CAE3B,MAAM,YAAY,OAAO,OAAO,WAAW;EACzC,WACE,IAAI,iBAAiB,6CAA6C,CAC/D,YAAY;GACX;GACA;GACA;GACD,CAAC,CACD,iBAAiB,MAAM,KAAK,CAC5B,UAAU,EAAE,QAAQ,MAAM,CAAC,CAC3B,iBACC,KAAK,cAAc,2CAA2C,CAC/D,CACA,mBAAmB,IAAO,CAC1B,OAAO;EACZ,QAAQ,0BAAU,IAAI,MAAM,8BAA8B,QAAQ;EACnE,CAAC;AAEF,QAAO,MAAM,aACX,OACA,OAAO,WAAW;EAChB,WAAW,UAAU,MAAM;EAC3B,QAAQ,0BAAU,IAAI,MAAM,6BAA6B,QAAQ;EAClE,CAAC,CAAC,KACD,OAAO,UAAU,OAAO,IAAI,iCAAiC,CAAC,EAC9D,OAAO,OAAO,UACZ,OAAO,IAAI,6BAA6B,QAAQ,CACjD,CACF,CACF;AAED,QAAO;EACL,aAAa,OAAO,WAAW,UAAU,cAAc,KAAK,CAAC;EAC7D,aAAa,OAAO,WAAW,UAAU,cAAc,KAAK,CAAC;EAC7D,aAAa,OAAO,IAAI,aAAa;GACnC,MAAM,OAAO,OAAO,OAAO,WAAW,UAAU,cAAc,KAAK,CAAC;AAEpE,UAAO,GADM,OAAO,OAAO,WAAW,UAAU,SAAS,CAAC,CAC3C,GAAG;IAClB;EACF,aAAa,OAAO,IAAI,aAAa;GACnC,MAAM,OAAO,OAAO,OAAO,WAAW,UAAU,cAAc,KAAK,CAAC;AAEpE,UAAO,GADM,OAAO,OAAO,WAAW,UAAU,SAAS,CAAC,CAC3C,GAAG;IAClB;EACF,cAAc,OAAO,QAAQ,UAAU;EACxC;EACD,CACH"}
@@ -1,121 +0,0 @@
1
- import type { CallOptions } from "nice-grpc";
2
- import { ArrowFlightClient } from "./arrow-flight";
3
- import { Any } from "./proto/any";
4
- import {
5
- FlightDescriptor,
6
- FlightDescriptor_DescriptorType,
7
- type FlightInfo,
8
- type FlightServiceDefinition,
9
- } from "./proto/Flight";
10
- import {
11
- CommandGetCatalogs,
12
- CommandGetDbSchemas,
13
- CommandGetTables,
14
- CommandGetTableTypes,
15
- CommandStatementQuery,
16
- } from "./proto/FlightSql";
17
- import type {
18
- ClientOptions,
19
- HostOrChannel,
20
- RemoveTypeUrl,
21
- } from "./proto-utils";
22
-
23
- export class ArrowFlightSqlClient {
24
- private inner: ArrowFlightClient;
25
-
26
- constructor(
27
- config: HostOrChannel,
28
- options: ClientOptions<FlightServiceDefinition> = {},
29
- ) {
30
- this.inner = new ArrowFlightClient(config, options);
31
- }
32
-
33
- executeFlightInfo(request: FlightInfo, options?: CallOptions) {
34
- return this.inner.executeFlightInfo(request, options);
35
- }
36
-
37
- async getCatalogs(
38
- request: RemoveTypeUrl<CommandGetCatalogs>,
39
- options?: CallOptions,
40
- ) {
41
- const descriptor = createCommandDescriptor(
42
- CommandGetCatalogs.$type,
43
- CommandGetCatalogs.encode({
44
- $type: CommandGetCatalogs.$type,
45
- ...request,
46
- }).finish(),
47
- );
48
- return this.inner.getFlightInfo(descriptor, options);
49
- }
50
-
51
- async getDbSchemas(
52
- request: RemoveTypeUrl<CommandGetDbSchemas>,
53
- options?: CallOptions,
54
- ) {
55
- const descriptor = createCommandDescriptor(
56
- CommandGetDbSchemas.$type,
57
- CommandGetDbSchemas.encode({
58
- $type: CommandGetDbSchemas.$type,
59
- ...request,
60
- }).finish(),
61
- );
62
- return this.inner.getFlightInfo(descriptor, options);
63
- }
64
-
65
- async getTables(
66
- request: RemoveTypeUrl<CommandGetTables>,
67
- options?: CallOptions,
68
- ) {
69
- const descriptor = createCommandDescriptor(
70
- CommandGetTables.$type,
71
- CommandGetTables.encode({
72
- $type: CommandGetTables.$type,
73
- ...request,
74
- }).finish(),
75
- );
76
- return this.inner.getFlightInfo(descriptor, options);
77
- }
78
-
79
- async getTableTypes(
80
- request: RemoveTypeUrl<CommandGetTableTypes>,
81
- options?: CallOptions,
82
- ) {
83
- const descriptor = createCommandDescriptor(
84
- CommandGetTableTypes.$type,
85
- CommandGetTableTypes.encode({
86
- $type: CommandGetTableTypes.$type,
87
- ...request,
88
- }).finish(),
89
- );
90
- return this.inner.getFlightInfo(descriptor, options);
91
- }
92
-
93
- async executeQuery(
94
- request: RemoveTypeUrl<CommandStatementQuery>,
95
- options?: CallOptions,
96
- ) {
97
- const descriptor = createCommandDescriptor(
98
- CommandStatementQuery.$type,
99
- CommandStatementQuery.encode({
100
- $type: CommandStatementQuery.$type,
101
- ...request,
102
- }).finish(),
103
- );
104
- return this.inner.getFlightInfo(descriptor, options);
105
- }
106
- }
107
-
108
- function createCommandDescriptor(
109
- typeUrl: string,
110
- value: Uint8Array,
111
- ): FlightDescriptor {
112
- const cmd = Any.create({
113
- typeUrl: `type.googleapis.com/${typeUrl}`,
114
- value,
115
- });
116
-
117
- return FlightDescriptor.create({
118
- type: FlightDescriptor_DescriptorType.CMD,
119
- cmd: Any.encode(cmd).finish(),
120
- });
121
- }
@@ -1,149 +0,0 @@
1
- import type { RecordBatch, Schema } from "apache-arrow";
2
- import { type CallOptions, createClient } from "nice-grpc";
3
- import {
4
- decodeFlightDataStream,
5
- decodeSchemaFromFlightInfo,
6
- } from "./arrow-utils";
7
- import {
8
- type FlightData,
9
- type FlightDescriptor,
10
- type FlightInfo,
11
- type FlightServiceClient,
12
- FlightServiceDefinition,
13
- type HandshakeRequest,
14
- type HandshakeResponse,
15
- type PutResult,
16
- type Ticket,
17
- } from "./proto/Flight";
18
- import {
19
- type ClientOptions,
20
- createChannelFromConfig,
21
- type HostOrChannel,
22
- } from "./proto-utils";
23
-
24
- export class ArrowFlightClient {
25
- private client: FlightServiceClient;
26
-
27
- constructor(
28
- config: HostOrChannel,
29
- options: ClientOptions<FlightServiceDefinition> = {},
30
- ) {
31
- const channel = createChannelFromConfig(config);
32
-
33
- this.client = createClient(
34
- FlightServiceDefinition,
35
- channel,
36
- options.defaultCallOptions,
37
- );
38
- }
39
-
40
- executeFlightInfo(
41
- info: FlightInfo,
42
- options?: CallOptions,
43
- ): AsyncGenerator<RecordBatch> {
44
- const schema = decodeSchemaFromFlightInfo(info);
45
- if (!schema) {
46
- throw new Error("FlightInfo must have a schema");
47
- }
48
-
49
- const client = this;
50
-
51
- return (async function* () {
52
- for (const endpoint of info.endpoint) {
53
- if (endpoint.ticket === undefined) {
54
- continue;
55
- }
56
-
57
- yield* client.doGet(endpoint.ticket, { schema, ...options });
58
- }
59
- })();
60
- }
61
-
62
- /**
63
- * Handshake between client and server.
64
- *
65
- * Depending on the server, the handshake may be required to determine the
66
- * token that should be used for future operations. Both request and response
67
- * are streams to allow multiple round-trips depending on auth mechanism.
68
- */
69
- handshake(
70
- request: AsyncIterable<HandshakeRequest>,
71
- options?: CallOptions,
72
- ): AsyncIterable<HandshakeResponse> {
73
- return this.client.handshake(request, options);
74
- }
75
-
76
- /** Get a list of available streams given a particular criteria. */
77
- // listFlights(
78
- // request: proto.arrow_flight.Criteria,
79
- // options?: ClientCallOptions,
80
- // ): AsyncIterable<proto.arrow_flight.FlightInfo>;
81
-
82
- getFlightInfo(
83
- request: FlightDescriptor,
84
- options?: CallOptions,
85
- ): Promise<FlightInfo> {
86
- return this.client.getFlightInfo(request, options);
87
- }
88
-
89
- // /** Start a query and get information to poll its execution status. */
90
- // pollFlightInfo(
91
- // request: proto.arrow_flight.FlightDescriptor,
92
- // options?: ClientCallOptions,
93
- // ): Promise<proto.arrow_flight.PollInfo>;
94
-
95
- // /** Get the schema for a given FlightDescriptor. */
96
- // getSchema(
97
- // request: proto.arrow_flight.FlightDescriptor,
98
- // options?: ClientCallOptions,
99
- // ): Promise<proto.arrow_flight.SchemaResult>;
100
-
101
- /**
102
- * Retrieve a single stream associated with a particular descriptor
103
- * associated with the referenced ticket. A Flight can be composed of one or
104
- * more streams where each stream can be retrieved using a separate opaque
105
- * ticket that the flight service uses for managing a collection of streams.
106
- */
107
- doGet(
108
- request: Ticket,
109
- options: { schema: Schema } & CallOptions,
110
- ): AsyncIterable<RecordBatch> {
111
- const { schema: expectedSchema } = options;
112
- return decodeFlightDataStream(this.client.doGet(request, options), {
113
- expectedSchema,
114
- });
115
- }
116
-
117
- /**
118
- * Push a stream to the flight service associated with a particular
119
- * flight stream. This allows a client of a flight service to upload a stream
120
- * of data. Depending on the particular flight service, a client consumer
121
- * could be allowed to upload a single stream per descriptor or an unlimited
122
- * number. In the latter, the service might implement a 'seal' action that
123
- * can be applied to a descriptor once all streams are uploaded.
124
- */
125
- doPut(
126
- request: AsyncIterable<FlightData>,
127
- options?: CallOptions,
128
- ): AsyncIterable<PutResult> {
129
- return this.client.doPut(request, options);
130
- }
131
-
132
- // /** Open a bidirectional data channel for a given descriptor. */
133
- // doExchange(
134
- // request: AsyncIterable<proto.arrow_flight.FlightData>,
135
- // options?: ClientCallOptions,
136
- // ): AsyncIterable<proto.arrow_flight.FlightData>;
137
-
138
- // /** Execute a specific action against the flight service. */
139
- // doAction(
140
- // request: proto.arrow_flight.Action,
141
- // options?: ClientCallOptions,
142
- // ): AsyncIterable<proto.arrow_flight.Result>;
143
-
144
- // /** Get all available action types. */
145
- // listActions(
146
- // request: proto.arrow_flight.Empty,
147
- // options?: ClientCallOptions,
148
- // ): AsyncIterable<proto.arrow_flight.ActionType>;
149
- }