@databricks/appkit 0.0.2

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 (166) hide show
  1. package/CLAUDE.md +3 -0
  2. package/DCO +25 -0
  3. package/LICENSE +203 -0
  4. package/NOTICE.md +73 -0
  5. package/README.md +35 -0
  6. package/bin/setup-claude.js +190 -0
  7. package/dist/_virtual/rolldown_runtime.js +39 -0
  8. package/dist/analytics/analytics.d.ts +31 -0
  9. package/dist/analytics/analytics.d.ts.map +1 -0
  10. package/dist/analytics/analytics.js +149 -0
  11. package/dist/analytics/analytics.js.map +1 -0
  12. package/dist/analytics/defaults.js +17 -0
  13. package/dist/analytics/defaults.js.map +1 -0
  14. package/dist/analytics/index.js +3 -0
  15. package/dist/analytics/query.js +50 -0
  16. package/dist/analytics/query.js.map +1 -0
  17. package/dist/analytics/types.d.ts +9 -0
  18. package/dist/analytics/types.d.ts.map +1 -0
  19. package/dist/app/index.d.ts +23 -0
  20. package/dist/app/index.d.ts.map +1 -0
  21. package/dist/app/index.js +49 -0
  22. package/dist/app/index.js.map +1 -0
  23. package/dist/appkit/package.js +7 -0
  24. package/dist/appkit/package.js.map +1 -0
  25. package/dist/cache/defaults.js +14 -0
  26. package/dist/cache/defaults.js.map +1 -0
  27. package/dist/cache/index.d.ts +119 -0
  28. package/dist/cache/index.d.ts.map +1 -0
  29. package/dist/cache/index.js +307 -0
  30. package/dist/cache/index.js.map +1 -0
  31. package/dist/cache/storage/defaults.js +16 -0
  32. package/dist/cache/storage/defaults.js.map +1 -0
  33. package/dist/cache/storage/index.js +4 -0
  34. package/dist/cache/storage/memory.js +87 -0
  35. package/dist/cache/storage/memory.js.map +1 -0
  36. package/dist/cache/storage/persistent.js +211 -0
  37. package/dist/cache/storage/persistent.js.map +1 -0
  38. package/dist/connectors/index.js +6 -0
  39. package/dist/connectors/lakebase/client.js +348 -0
  40. package/dist/connectors/lakebase/client.js.map +1 -0
  41. package/dist/connectors/lakebase/defaults.js +13 -0
  42. package/dist/connectors/lakebase/defaults.js.map +1 -0
  43. package/dist/connectors/lakebase/index.js +3 -0
  44. package/dist/connectors/sql-warehouse/client.js +284 -0
  45. package/dist/connectors/sql-warehouse/client.js.map +1 -0
  46. package/dist/connectors/sql-warehouse/defaults.js +12 -0
  47. package/dist/connectors/sql-warehouse/defaults.js.map +1 -0
  48. package/dist/connectors/sql-warehouse/index.js +3 -0
  49. package/dist/core/appkit.d.ts +14 -0
  50. package/dist/core/appkit.d.ts.map +1 -0
  51. package/dist/core/appkit.js +66 -0
  52. package/dist/core/appkit.js.map +1 -0
  53. package/dist/core/index.js +3 -0
  54. package/dist/index.d.ts +15 -0
  55. package/dist/index.js +21 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/plugin/dev-reader.d.ts +20 -0
  58. package/dist/plugin/dev-reader.d.ts.map +1 -0
  59. package/dist/plugin/dev-reader.js +63 -0
  60. package/dist/plugin/dev-reader.js.map +1 -0
  61. package/dist/plugin/index.js +4 -0
  62. package/dist/plugin/interceptors/cache.js +15 -0
  63. package/dist/plugin/interceptors/cache.js.map +1 -0
  64. package/dist/plugin/interceptors/retry.js +32 -0
  65. package/dist/plugin/interceptors/retry.js.map +1 -0
  66. package/dist/plugin/interceptors/telemetry.js +33 -0
  67. package/dist/plugin/interceptors/telemetry.js.map +1 -0
  68. package/dist/plugin/interceptors/timeout.js +35 -0
  69. package/dist/plugin/interceptors/timeout.js.map +1 -0
  70. package/dist/plugin/plugin.d.ts +43 -0
  71. package/dist/plugin/plugin.d.ts.map +1 -0
  72. package/dist/plugin/plugin.js +119 -0
  73. package/dist/plugin/plugin.js.map +1 -0
  74. package/dist/plugin/to-plugin.d.ts +7 -0
  75. package/dist/plugin/to-plugin.d.ts.map +1 -0
  76. package/dist/plugin/to-plugin.js +12 -0
  77. package/dist/plugin/to-plugin.js.map +1 -0
  78. package/dist/server/base-server.js +24 -0
  79. package/dist/server/base-server.js.map +1 -0
  80. package/dist/server/index.d.ts +100 -0
  81. package/dist/server/index.d.ts.map +1 -0
  82. package/dist/server/index.js +224 -0
  83. package/dist/server/index.js.map +1 -0
  84. package/dist/server/remote-tunnel/denied.html +68 -0
  85. package/dist/server/remote-tunnel/gate.js +51 -0
  86. package/dist/server/remote-tunnel/gate.js.map +1 -0
  87. package/dist/server/remote-tunnel/index.html +165 -0
  88. package/dist/server/remote-tunnel/remote-tunnel-controller.js +100 -0
  89. package/dist/server/remote-tunnel/remote-tunnel-controller.js.map +1 -0
  90. package/dist/server/remote-tunnel/remote-tunnel-manager.js +320 -0
  91. package/dist/server/remote-tunnel/remote-tunnel-manager.js.map +1 -0
  92. package/dist/server/remote-tunnel/wait.html +158 -0
  93. package/dist/server/static-server.js +47 -0
  94. package/dist/server/static-server.js.map +1 -0
  95. package/dist/server/types.d.ts +14 -0
  96. package/dist/server/types.d.ts.map +1 -0
  97. package/dist/server/utils.js +70 -0
  98. package/dist/server/utils.js.map +1 -0
  99. package/dist/server/vite-dev-server.js +103 -0
  100. package/dist/server/vite-dev-server.js.map +1 -0
  101. package/dist/shared/src/cache.d.ts +62 -0
  102. package/dist/shared/src/cache.d.ts.map +1 -0
  103. package/dist/shared/src/execute.d.ts +46 -0
  104. package/dist/shared/src/execute.d.ts.map +1 -0
  105. package/dist/shared/src/plugin.d.ts +50 -0
  106. package/dist/shared/src/plugin.d.ts.map +1 -0
  107. package/dist/shared/src/sql/helpers.d.ts +160 -0
  108. package/dist/shared/src/sql/helpers.d.ts.map +1 -0
  109. package/dist/shared/src/sql/helpers.js +103 -0
  110. package/dist/shared/src/sql/helpers.js.map +1 -0
  111. package/dist/shared/src/sql/types.d.ts +34 -0
  112. package/dist/shared/src/sql/types.d.ts.map +1 -0
  113. package/dist/shared/src/tunnel.d.ts +30 -0
  114. package/dist/shared/src/tunnel.d.ts.map +1 -0
  115. package/dist/stream/arrow-stream-processor.js +154 -0
  116. package/dist/stream/arrow-stream-processor.js.map +1 -0
  117. package/dist/stream/buffers.js +88 -0
  118. package/dist/stream/buffers.js.map +1 -0
  119. package/dist/stream/defaults.js +14 -0
  120. package/dist/stream/defaults.js.map +1 -0
  121. package/dist/stream/index.js +6 -0
  122. package/dist/stream/sse-writer.js +61 -0
  123. package/dist/stream/sse-writer.js.map +1 -0
  124. package/dist/stream/stream-manager.d.ts +27 -0
  125. package/dist/stream/stream-manager.d.ts.map +1 -0
  126. package/dist/stream/stream-manager.js +191 -0
  127. package/dist/stream/stream-manager.js.map +1 -0
  128. package/dist/stream/stream-registry.js +54 -0
  129. package/dist/stream/stream-registry.js.map +1 -0
  130. package/dist/stream/types.js +14 -0
  131. package/dist/stream/types.js.map +1 -0
  132. package/dist/stream/validator.js +25 -0
  133. package/dist/stream/validator.js.map +1 -0
  134. package/dist/telemetry/config.js +20 -0
  135. package/dist/telemetry/config.js.map +1 -0
  136. package/dist/telemetry/index.d.ts +4 -0
  137. package/dist/telemetry/index.js +8 -0
  138. package/dist/telemetry/instrumentations.js +38 -0
  139. package/dist/telemetry/instrumentations.js.map +1 -0
  140. package/dist/telemetry/noop.js +54 -0
  141. package/dist/telemetry/noop.js.map +1 -0
  142. package/dist/telemetry/telemetry-manager.js +113 -0
  143. package/dist/telemetry/telemetry-manager.js.map +1 -0
  144. package/dist/telemetry/telemetry-provider.js +82 -0
  145. package/dist/telemetry/telemetry-provider.js.map +1 -0
  146. package/dist/telemetry/types.d.ts +74 -0
  147. package/dist/telemetry/types.d.ts.map +1 -0
  148. package/dist/type-generator/vite-plugin.d.ts +22 -0
  149. package/dist/type-generator/vite-plugin.d.ts.map +1 -0
  150. package/dist/type-generator/vite-plugin.js +49 -0
  151. package/dist/type-generator/vite-plugin.js.map +1 -0
  152. package/dist/utils/databricks-client-middleware.d.ts +17 -0
  153. package/dist/utils/databricks-client-middleware.d.ts.map +1 -0
  154. package/dist/utils/databricks-client-middleware.js +117 -0
  155. package/dist/utils/databricks-client-middleware.js.map +1 -0
  156. package/dist/utils/env-validator.js +14 -0
  157. package/dist/utils/env-validator.js.map +1 -0
  158. package/dist/utils/index.js +26 -0
  159. package/dist/utils/index.js.map +1 -0
  160. package/dist/utils/merge.js +25 -0
  161. package/dist/utils/merge.js.map +1 -0
  162. package/dist/utils/vite-config-merge.js +22 -0
  163. package/dist/utils/vite-config-merge.js.map +1 -0
  164. package/llms.txt +193 -0
  165. package/package.json +70 -0
  166. package/scripts/postinstall.js +6 -0
@@ -0,0 +1,284 @@
1
+ import { TelemetryManager } from "../../telemetry/telemetry-manager.js";
2
+ import { SpanKind, SpanStatusCode } from "../../telemetry/index.js";
3
+ import { ArrowStreamProcessor } from "../../stream/arrow-stream-processor.js";
4
+ import { executeStatementDefaults } from "./defaults.js";
5
+ import { Context } from "@databricks/sdk-experimental";
6
+
7
+ //#region src/connectors/sql-warehouse/client.ts
8
+ var SQLWarehouseConnector = class {
9
+ constructor(config) {
10
+ this.name = "sql-warehouse";
11
+ this._arrowProcessor = null;
12
+ this.config = config;
13
+ this.telemetry = TelemetryManager.getProvider(this.name, this.config.telemetry);
14
+ this.telemetryMetrics = {
15
+ queryCount: this.telemetry.getMeter().createCounter("query.count", {
16
+ description: "Total number of queries executed",
17
+ unit: "1"
18
+ }),
19
+ queryDuration: this.telemetry.getMeter().createHistogram("query.duration", {
20
+ description: "Duration of queries executed",
21
+ unit: "ms"
22
+ })
23
+ };
24
+ }
25
+ /**
26
+ * Lazily initializes and returns the ArrowStreamProcessor.
27
+ * Only created on first Arrow format query to avoid unnecessary allocation.
28
+ */
29
+ get arrowProcessor() {
30
+ if (!this._arrowProcessor) this._arrowProcessor = new ArrowStreamProcessor({
31
+ timeout: this.config.timeout || executeStatementDefaults.timeout,
32
+ maxConcurrentDownloads: ArrowStreamProcessor.DEFAULT_MAX_CONCURRENT_DOWNLOADS,
33
+ retries: ArrowStreamProcessor.DEFAULT_RETRIES
34
+ });
35
+ return this._arrowProcessor;
36
+ }
37
+ async executeStatement(workspaceClient, input, signal) {
38
+ const startTime = Date.now();
39
+ let success = false;
40
+ return this.telemetry.startActiveSpan("sql.query", {
41
+ kind: SpanKind.CLIENT,
42
+ attributes: {
43
+ "db.system": "databricks",
44
+ "db.warehouse_id": input.warehouse_id || "",
45
+ "db.catalog": input.catalog ?? "",
46
+ "db.schema": input.schema ?? "",
47
+ "db.statement": input.statement?.substring(0, 500) || "",
48
+ "db.has_parameters": !!input.parameters
49
+ }
50
+ }, async (span) => {
51
+ try {
52
+ if (!input.statement) throw new Error("Statement is required: Please provide a SQL statement to execute");
53
+ if (!input.warehouse_id) throw new Error("Warehouse ID is required: Please provide a warehouse_id to execute the statement");
54
+ const body = {
55
+ statement: input.statement,
56
+ parameters: input.parameters,
57
+ warehouse_id: input.warehouse_id,
58
+ catalog: input.catalog,
59
+ schema: input.schema,
60
+ wait_timeout: input.wait_timeout || executeStatementDefaults.wait_timeout,
61
+ disposition: input.disposition || executeStatementDefaults.disposition,
62
+ format: input.format || executeStatementDefaults.format,
63
+ byte_limit: input.byte_limit,
64
+ row_limit: input.row_limit,
65
+ on_wait_timeout: input.on_wait_timeout || executeStatementDefaults.on_wait_timeout
66
+ };
67
+ span.addEvent("statement.submitting", { "db.warehouse_id": input.warehouse_id });
68
+ const response = await workspaceClient.statementExecution.executeStatement(body, this._createContext(signal));
69
+ if (!response) throw new Error("No response received from SQL Warehouse API");
70
+ const status = response.status;
71
+ const statementId = response.statement_id;
72
+ span.setAttribute("db.statement_id", statementId);
73
+ span.addEvent("statement.submitted", {
74
+ "db.statement_id": response.statement_id,
75
+ "db.status": status?.state
76
+ });
77
+ let result;
78
+ switch (status?.state) {
79
+ case "RUNNING":
80
+ case "PENDING":
81
+ span.addEvent("statement.polling_started", { "db.status": response.status?.state });
82
+ result = await this._pollForStatementResult(workspaceClient, statementId, this.config.timeout, signal);
83
+ break;
84
+ case "SUCCEEDED":
85
+ result = this._transformDataArray(response);
86
+ break;
87
+ case "FAILED": throw new Error(`Statement failed: ${status.error?.message || "Unknown error"}`);
88
+ case "CANCELED": throw new Error("Statement was canceled");
89
+ case "CLOSED": throw new Error("Statement execution completed but results are no longer available (CLOSED state)");
90
+ default: throw new Error(`Unknown statement state: ${status?.state}`);
91
+ }
92
+ const resultData = result.result;
93
+ if (resultData?.data) span.setAttribute("db.result.row_count", resultData.data.length);
94
+ else if (resultData?.data_array) span.setAttribute("db.result.row_count", resultData.data_array.length);
95
+ success = true;
96
+ span.setStatus({ code: SpanStatusCode.OK });
97
+ return result;
98
+ } catch (error) {
99
+ span.recordException(error);
100
+ span.setStatus({
101
+ code: SpanStatusCode.ERROR,
102
+ message: error instanceof Error ? error.message : String(error)
103
+ });
104
+ throw error;
105
+ } finally {
106
+ const duration = Date.now() - startTime;
107
+ span.end();
108
+ const attributes = {
109
+ "db.warehouse_id": input.warehouse_id,
110
+ "db.catalog": input.catalog ?? "",
111
+ "db.schema": input.schema ?? "",
112
+ "db.statement": input.statement?.substring(0, 500) || "",
113
+ success: success.toString()
114
+ };
115
+ this.telemetryMetrics.queryCount.add(1, attributes);
116
+ this.telemetryMetrics.queryDuration.record(duration, attributes);
117
+ }
118
+ }, {
119
+ name: this.name,
120
+ includePrefix: true
121
+ });
122
+ }
123
+ async _pollForStatementResult(workspaceClient, statementId, timeout = executeStatementDefaults.timeout, signal) {
124
+ return this.telemetry.startActiveSpan("sql.poll", { attributes: {
125
+ "db.statement_id": statementId,
126
+ "db.polling.timeout": timeout
127
+ } }, async (span) => {
128
+ try {
129
+ const startTime = Date.now();
130
+ let delay = 1e3;
131
+ const maxDelayBetweenPolls = 5e3;
132
+ let pollCount = 0;
133
+ while (true) {
134
+ pollCount++;
135
+ span.setAttribute("db.polling.current_attempt", pollCount);
136
+ const elapsedTime = Date.now() - startTime;
137
+ if (elapsedTime > timeout) {
138
+ const error = /* @__PURE__ */ new Error(`Statement polling timeout exceeded after ${timeout}ms (elapsed: ${elapsedTime}ms)`);
139
+ span.recordException(error);
140
+ span.setStatus({ code: SpanStatusCode.ERROR });
141
+ throw error;
142
+ }
143
+ if (signal?.aborted) {
144
+ const error = /* @__PURE__ */ new Error("Request aborted");
145
+ span.recordException(error);
146
+ span.setStatus({ code: SpanStatusCode.ERROR });
147
+ throw error;
148
+ }
149
+ span.addEvent("polling.attempt", {
150
+ "poll.attempt": pollCount,
151
+ "poll.delay_ms": delay,
152
+ "poll.elapsed_ms": elapsedTime
153
+ });
154
+ const response = await workspaceClient.statementExecution.getStatement({ statement_id: statementId }, this._createContext(signal));
155
+ if (!response) throw new Error("No response received from SQL Warehouse API");
156
+ const status = response.status;
157
+ span.addEvent("polling.status_check", {
158
+ "db.status": status?.state,
159
+ "poll.attempt": pollCount
160
+ });
161
+ switch (status?.state) {
162
+ case "PENDING":
163
+ case "RUNNING": break;
164
+ case "SUCCEEDED":
165
+ span.setAttribute("db.polling.attempts", pollCount);
166
+ span.setAttribute("db.polling.total_duration_ms", elapsedTime);
167
+ span.addEvent("polling.completed", {
168
+ "poll.attempts": pollCount,
169
+ "poll.duration_ms": elapsedTime
170
+ });
171
+ span.setStatus({ code: SpanStatusCode.OK });
172
+ return this._transformDataArray(response);
173
+ case "FAILED": throw new Error(`Statement failed: ${status.error?.message || "Unknown error"}`);
174
+ case "CANCELED": throw new Error("Statement was canceled");
175
+ case "CLOSED": throw new Error("Statement execution completed but results are no longer available (CLOSED state)");
176
+ default: throw new Error(`Unknown statement state: ${status?.state}`);
177
+ }
178
+ await new Promise((resolve) => setTimeout(resolve, delay));
179
+ delay = Math.min(delay * 2, maxDelayBetweenPolls);
180
+ }
181
+ } catch (error) {
182
+ span.recordException(error);
183
+ span.setStatus({
184
+ code: SpanStatusCode.ERROR,
185
+ message: error instanceof Error ? error.message : String(error)
186
+ });
187
+ throw error;
188
+ } finally {
189
+ span.end();
190
+ }
191
+ }, {
192
+ name: this.name,
193
+ includePrefix: true
194
+ });
195
+ }
196
+ _transformDataArray(response) {
197
+ if (response.manifest?.format === "ARROW_STREAM") return this.updateWithArrowStatus(response);
198
+ if (!response.result?.data_array || !response.manifest?.schema?.columns) return response;
199
+ const columns = response.manifest.schema.columns;
200
+ const transformedData = response.result.data_array.map((row) => {
201
+ const obj = {};
202
+ row.forEach((value, index) => {
203
+ const column = columns[index];
204
+ const columnName = column?.name || `column_${index}`;
205
+ if (column?.type_name === "STRING" && typeof value === "string" && value && (value[0] === "{" || value[0] === "[")) try {
206
+ obj[columnName] = JSON.parse(value);
207
+ } catch {
208
+ obj[columnName] = value;
209
+ }
210
+ else obj[columnName] = value;
211
+ });
212
+ return obj;
213
+ });
214
+ const { data_array: _data_array, ...restResult } = response.result;
215
+ return {
216
+ ...response,
217
+ result: {
218
+ ...restResult,
219
+ data: transformedData
220
+ }
221
+ };
222
+ }
223
+ updateWithArrowStatus(response) {
224
+ return { result: {
225
+ statement_id: response.statement_id,
226
+ status: {
227
+ state: response.status?.state,
228
+ error: response.status?.error
229
+ }
230
+ } };
231
+ }
232
+ async getArrowData(workspaceClient, jobId, signal) {
233
+ const startTime = Date.now();
234
+ return this.telemetry.startActiveSpan("arrow.getData", {
235
+ kind: SpanKind.CLIENT,
236
+ attributes: {
237
+ "db.system": "databricks",
238
+ "arrow.job_id": jobId
239
+ }
240
+ }, async (span) => {
241
+ try {
242
+ const response = await workspaceClient.statementExecution.getStatement({ statement_id: jobId }, this._createContext(signal));
243
+ const chunks = response.result?.external_links;
244
+ const schema = response.manifest?.schema;
245
+ if (!chunks || !schema) throw new Error("No chunks or schema found in response");
246
+ span.setAttribute("arrow.chunk_count", chunks.length);
247
+ const result = await this.arrowProcessor.processChunks(chunks, schema, signal);
248
+ span.setAttribute("arrow.data_size_bytes", result.data.length);
249
+ span.setStatus({ code: SpanStatusCode.OK });
250
+ const duration = Date.now() - startTime;
251
+ this.telemetryMetrics.queryDuration.record(duration, {
252
+ operation: "arrow.getData",
253
+ status: "success"
254
+ });
255
+ return result;
256
+ } catch (error) {
257
+ span.setStatus({
258
+ code: SpanStatusCode.ERROR,
259
+ message: error instanceof Error ? error.message : "Unknown error"
260
+ });
261
+ span.recordException(error);
262
+ const duration = Date.now() - startTime;
263
+ this.telemetryMetrics.queryDuration.record(duration, {
264
+ operation: "arrow.getData",
265
+ status: "error"
266
+ });
267
+ console.error(`Failed Arrow job: ${jobId}`, error);
268
+ throw error;
269
+ }
270
+ });
271
+ }
272
+ _createContext(signal) {
273
+ return new Context({ cancellationToken: {
274
+ isCancellationRequested: signal?.aborted ?? false,
275
+ onCancellationRequested: (cb) => {
276
+ signal?.addEventListener("abort", cb, { once: true });
277
+ }
278
+ } });
279
+ }
280
+ };
281
+
282
+ //#endregion
283
+ export { SQLWarehouseConnector };
284
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","names":["body: sql.ExecuteStatementRequest","result:\n | sql.StatementResponse\n | { result: { statement_id: string; status: sql.StatementStatus } }","obj: Record<string, unknown>"],"sources":["../../../src/connectors/sql-warehouse/client.ts"],"sourcesContent":["import {\n Context,\n type sql,\n type WorkspaceClient,\n} from \"@databricks/sdk-experimental\";\nimport { ArrowStreamProcessor } from \"../../stream/arrow-stream-processor\";\nimport type { TelemetryOptions } from \"shared\";\nimport type { TelemetryProvider } from \"../../telemetry\";\nimport {\n type Counter,\n type Histogram,\n type Span,\n SpanKind,\n SpanStatusCode,\n TelemetryManager,\n} from \"../../telemetry\";\nimport { executeStatementDefaults } from \"./defaults\";\n\nexport interface SQLWarehouseConfig {\n timeout?: number;\n telemetry?: TelemetryOptions;\n}\n\nexport class SQLWarehouseConnector {\n private readonly name = \"sql-warehouse\";\n\n private config: SQLWarehouseConfig;\n\n // Lazy-initialized: only created when Arrow format is used\n private _arrowProcessor: ArrowStreamProcessor | null = null;\n // telemetry\n private readonly telemetry: TelemetryProvider;\n private readonly telemetryMetrics: {\n queryCount: Counter;\n queryDuration: Histogram;\n };\n\n constructor(config: SQLWarehouseConfig) {\n this.config = config;\n\n this.telemetry = TelemetryManager.getProvider(\n this.name,\n this.config.telemetry,\n );\n this.telemetryMetrics = {\n queryCount: this.telemetry.getMeter().createCounter(\"query.count\", {\n description: \"Total number of queries executed\",\n unit: \"1\",\n }),\n queryDuration: this.telemetry\n .getMeter()\n .createHistogram(\"query.duration\", {\n description: \"Duration of queries executed\",\n unit: \"ms\",\n }),\n };\n }\n\n /**\n * Lazily initializes and returns the ArrowStreamProcessor.\n * Only created on first Arrow format query to avoid unnecessary allocation.\n */\n private get arrowProcessor(): ArrowStreamProcessor {\n if (!this._arrowProcessor) {\n this._arrowProcessor = new ArrowStreamProcessor({\n timeout: this.config.timeout || executeStatementDefaults.timeout,\n maxConcurrentDownloads:\n ArrowStreamProcessor.DEFAULT_MAX_CONCURRENT_DOWNLOADS,\n retries: ArrowStreamProcessor.DEFAULT_RETRIES,\n });\n }\n return this._arrowProcessor;\n }\n\n async executeStatement(\n workspaceClient: WorkspaceClient,\n input: sql.ExecuteStatementRequest,\n signal?: AbortSignal,\n ) {\n const startTime = Date.now();\n let success = false;\n\n return this.telemetry.startActiveSpan(\n \"sql.query\",\n {\n kind: SpanKind.CLIENT,\n attributes: {\n \"db.system\": \"databricks\",\n \"db.warehouse_id\": input.warehouse_id || \"\",\n \"db.catalog\": input.catalog ?? \"\",\n \"db.schema\": input.schema ?? \"\",\n \"db.statement\": input.statement?.substring(0, 500) || \"\",\n \"db.has_parameters\": !!input.parameters,\n },\n },\n async (span: Span) => {\n try {\n // validate required fields\n if (!input.statement) {\n throw new Error(\n \"Statement is required: Please provide a SQL statement to execute\",\n );\n }\n\n if (!input.warehouse_id) {\n throw new Error(\n \"Warehouse ID is required: Please provide a warehouse_id to execute the statement\",\n );\n }\n\n const body: sql.ExecuteStatementRequest = {\n statement: input.statement,\n parameters: input.parameters,\n warehouse_id: input.warehouse_id,\n catalog: input.catalog,\n schema: input.schema,\n wait_timeout:\n input.wait_timeout || executeStatementDefaults.wait_timeout,\n disposition:\n input.disposition || executeStatementDefaults.disposition,\n format: input.format || executeStatementDefaults.format,\n byte_limit: input.byte_limit,\n row_limit: input.row_limit,\n on_wait_timeout:\n input.on_wait_timeout || executeStatementDefaults.on_wait_timeout,\n };\n\n span.addEvent(\"statement.submitting\", {\n \"db.warehouse_id\": input.warehouse_id,\n });\n\n const response =\n await workspaceClient.statementExecution.executeStatement(\n body,\n this._createContext(signal),\n );\n\n if (!response) {\n throw new Error(\"No response received from SQL Warehouse API\");\n }\n const status = response.status;\n const statementId = response.statement_id as string;\n\n span.setAttribute(\"db.statement_id\", statementId);\n span.addEvent(\"statement.submitted\", {\n \"db.statement_id\": response.statement_id,\n \"db.status\": status?.state,\n });\n\n let result:\n | sql.StatementResponse\n | { result: { statement_id: string; status: sql.StatementStatus } };\n\n switch (status?.state) {\n case \"RUNNING\":\n case \"PENDING\":\n span.addEvent(\"statement.polling_started\", {\n \"db.status\": response.status?.state,\n });\n result = await this._pollForStatementResult(\n workspaceClient,\n statementId,\n this.config.timeout,\n signal,\n );\n break;\n case \"SUCCEEDED\":\n result = this._transformDataArray(response);\n break;\n case \"FAILED\":\n throw new Error(\n `Statement failed: ${status.error?.message || \"Unknown error\"}`,\n );\n case \"CANCELED\":\n throw new Error(\"Statement was canceled\");\n case \"CLOSED\":\n throw new Error(\n \"Statement execution completed but results are no longer available (CLOSED state)\",\n );\n default:\n throw new Error(`Unknown statement state: ${status?.state}`);\n }\n\n const resultData = result.result as any;\n if (resultData?.data) {\n span.setAttribute(\"db.result.row_count\", resultData.data.length);\n } else if (resultData?.data_array) {\n span.setAttribute(\n \"db.result.row_count\",\n resultData.data_array.length,\n );\n }\n\n success = true;\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.recordException(error as Error);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : String(error),\n });\n throw error;\n } finally {\n const duration = Date.now() - startTime;\n span.end();\n\n const attributes = {\n \"db.warehouse_id\": input.warehouse_id,\n \"db.catalog\": input.catalog ?? \"\",\n \"db.schema\": input.schema ?? \"\",\n \"db.statement\": input.statement?.substring(0, 500) || \"\",\n success: success.toString(),\n };\n\n this.telemetryMetrics.queryCount.add(1, attributes);\n this.telemetryMetrics.queryDuration.record(duration, attributes);\n }\n },\n { name: this.name, includePrefix: true },\n );\n }\n\n private async _pollForStatementResult(\n workspaceClient: WorkspaceClient,\n statementId: string,\n timeout = executeStatementDefaults.timeout,\n signal?: AbortSignal,\n ) {\n return this.telemetry.startActiveSpan(\n \"sql.poll\",\n {\n attributes: {\n \"db.statement_id\": statementId,\n \"db.polling.timeout\": timeout,\n },\n },\n async (span: Span) => {\n try {\n const startTime = Date.now();\n let delay = 1000;\n const maxDelayBetweenPolls = 5000; // max 5 seconds between polls\n let pollCount = 0;\n\n while (true) {\n pollCount++;\n span.setAttribute(\"db.polling.current_attempt\", pollCount);\n\n // check if timeout exceeded\n const elapsedTime = Date.now() - startTime;\n if (elapsedTime > timeout) {\n const error = new Error(\n `Statement polling timeout exceeded after ${timeout}ms (elapsed: ${elapsedTime}ms)`,\n );\n span.recordException(error);\n span.setStatus({ code: SpanStatusCode.ERROR });\n throw error;\n }\n\n if (signal?.aborted) {\n const error = new Error(\"Request aborted\");\n span.recordException(error);\n span.setStatus({ code: SpanStatusCode.ERROR });\n throw error;\n }\n\n span.addEvent(\"polling.attempt\", {\n \"poll.attempt\": pollCount,\n \"poll.delay_ms\": delay,\n \"poll.elapsed_ms\": elapsedTime,\n });\n\n const response =\n await workspaceClient.statementExecution.getStatement(\n {\n statement_id: statementId,\n },\n this._createContext(signal),\n );\n if (!response) {\n throw new Error(\"No response received from SQL Warehouse API\");\n }\n\n const status = response.status;\n\n span.addEvent(\"polling.status_check\", {\n \"db.status\": status?.state,\n \"poll.attempt\": pollCount,\n });\n\n switch (status?.state) {\n case \"PENDING\":\n case \"RUNNING\":\n // continue polling\n break;\n case \"SUCCEEDED\":\n span.setAttribute(\"db.polling.attempts\", pollCount);\n span.setAttribute(\"db.polling.total_duration_ms\", elapsedTime);\n span.addEvent(\"polling.completed\", {\n \"poll.attempts\": pollCount,\n \"poll.duration_ms\": elapsedTime,\n });\n span.setStatus({ code: SpanStatusCode.OK });\n return this._transformDataArray(response);\n case \"FAILED\":\n throw new Error(\n `Statement failed: ${\n status.error?.message || \"Unknown error\"\n }`,\n );\n case \"CANCELED\":\n throw new Error(\"Statement was canceled\");\n case \"CLOSED\":\n throw new Error(\n \"Statement execution completed but results are no longer available (CLOSED state)\",\n );\n default:\n throw new Error(`Unknown statement state: ${status?.state}`);\n }\n\n // continue polling after delay\n await new Promise((resolve) => setTimeout(resolve, delay));\n delay = Math.min(delay * 2, maxDelayBetweenPolls);\n }\n } catch (error) {\n span.recordException(error as Error);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : String(error),\n });\n throw error;\n } finally {\n span.end();\n }\n },\n { name: this.name, includePrefix: true },\n );\n }\n\n private _transformDataArray(response: sql.StatementResponse) {\n if (response.manifest?.format === \"ARROW_STREAM\") {\n return this.updateWithArrowStatus(response);\n }\n\n if (!response.result?.data_array || !response.manifest?.schema?.columns) {\n return response;\n }\n\n const columns = response.manifest.schema.columns;\n\n const transformedData = response.result.data_array.map((row) => {\n const obj: Record<string, unknown> = {};\n row.forEach((value, index) => {\n const column = columns[index];\n const columnName = column?.name || `column_${index}`;\n\n // attempt to parse JSON strings for string columns\n if (\n column?.type_name === \"STRING\" &&\n typeof value === \"string\" &&\n value &&\n (value[0] === \"{\" || value[0] === \"[\")\n ) {\n try {\n obj[columnName] = JSON.parse(value);\n } catch {\n // if parsing fails, keep as string\n obj[columnName] = value;\n }\n } else {\n obj[columnName] = value;\n }\n });\n return obj;\n });\n\n // remove data_array\n const { data_array: _data_array, ...restResult } = response.result;\n return {\n ...response,\n result: {\n ...restResult,\n data: transformedData,\n },\n };\n }\n\n private updateWithArrowStatus(response: sql.StatementResponse): {\n result: { statement_id: string; status: sql.StatementStatus };\n } {\n return {\n result: {\n statement_id: response.statement_id as string,\n status: {\n state: response.status?.state,\n error: response.status?.error,\n } as sql.StatementStatus,\n },\n };\n }\n\n async getArrowData(\n workspaceClient: WorkspaceClient,\n jobId: string,\n signal?: AbortSignal,\n ): Promise<ReturnType<typeof this.arrowProcessor.processChunks>> {\n const startTime = Date.now();\n\n return this.telemetry.startActiveSpan(\n \"arrow.getData\",\n {\n kind: SpanKind.CLIENT,\n attributes: {\n \"db.system\": \"databricks\",\n \"arrow.job_id\": jobId,\n },\n },\n async (span: Span) => {\n try {\n const response =\n await workspaceClient.statementExecution.getStatement(\n { statement_id: jobId },\n this._createContext(signal),\n );\n\n const chunks = response.result?.external_links;\n const schema = response.manifest?.schema;\n\n if (!chunks || !schema) {\n throw new Error(\"No chunks or schema found in response\");\n }\n\n span.setAttribute(\"arrow.chunk_count\", chunks.length);\n\n const result = await this.arrowProcessor.processChunks(\n chunks,\n schema,\n signal,\n );\n\n span.setAttribute(\"arrow.data_size_bytes\", result.data.length);\n span.setStatus({ code: SpanStatusCode.OK });\n\n const duration = Date.now() - startTime;\n this.telemetryMetrics.queryDuration.record(duration, {\n operation: \"arrow.getData\",\n status: \"success\",\n });\n\n return result;\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : \"Unknown error\",\n });\n span.recordException(error as Error);\n\n const duration = Date.now() - startTime;\n this.telemetryMetrics.queryDuration.record(duration, {\n operation: \"arrow.getData\",\n status: \"error\",\n });\n\n console.error(`Failed Arrow job: ${jobId}`, error);\n throw error;\n }\n },\n );\n }\n\n // create context for cancellation token\n private _createContext(signal?: AbortSignal) {\n return new Context({\n cancellationToken: {\n isCancellationRequested: signal?.aborted ?? false,\n onCancellationRequested: (cb: () => void) => {\n signal?.addEventListener(\"abort\", cb, { once: true });\n },\n },\n });\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ //#region src/connectors/sql-warehouse/defaults.ts
2
+ const executeStatementDefaults = {
3
+ wait_timeout: "30s",
4
+ disposition: "INLINE",
5
+ format: "JSON_ARRAY",
6
+ on_wait_timeout: "CONTINUE",
7
+ timeout: 6e4
8
+ };
9
+
10
+ //#endregion
11
+ export { executeStatementDefaults };
12
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","names":["executeStatementDefaults: ExecuteStatementDefaults"],"sources":["../../../src/connectors/sql-warehouse/defaults.ts"],"sourcesContent":["import type { sql } from \"@databricks/sdk-experimental\";\n\ninterface ExecuteStatementDefaults {\n wait_timeout: string;\n disposition: sql.ExecuteStatementRequest[\"disposition\"];\n format: sql.ExecuteStatementRequest[\"format\"];\n on_wait_timeout: sql.ExecuteStatementRequest[\"on_wait_timeout\"];\n timeout: number;\n}\n\n// @TODO: Make these configurable globally and validate right values\nexport const executeStatementDefaults: ExecuteStatementDefaults = {\n wait_timeout: \"30s\",\n disposition: \"INLINE\",\n format: \"JSON_ARRAY\",\n on_wait_timeout: \"CONTINUE\",\n timeout: 60000,\n};\n"],"mappings":";AAWA,MAAaA,2BAAqD;CAChE,cAAc;CACd,aAAa;CACb,QAAQ;CACR,iBAAiB;CACjB,SAAS;CACV"}
@@ -0,0 +1,3 @@
1
+ import { SQLWarehouseConnector } from "./client.js";
2
+
3
+ export { };
@@ -0,0 +1,14 @@
1
+ import { PluginConstructor, PluginData, PluginMap } from "../shared/src/plugin.js";
2
+ import { CacheConfig } from "../shared/src/cache.js";
3
+ import { TelemetryConfig } from "../telemetry/types.js";
4
+
5
+ //#region src/core/appkit.d.ts
6
+
7
+ declare function createApp<T extends PluginData<PluginConstructor, unknown, string>[]>(config?: {
8
+ plugins?: T;
9
+ telemetry?: TelemetryConfig;
10
+ cache?: CacheConfig;
11
+ }): Promise<PluginMap<T>>;
12
+ //#endregion
13
+ export { createApp };
14
+ //# sourceMappingURL=appkit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appkit.d.ts","names":[],"sources":["../../src/core/appkit.ts"],"sourcesContent":[],"mappings":";;;;;;AAmIU,iBARY,SAQZ,CAAA,UAPE,UAOF,CAPa,iBAOb,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,CAAA,CAAA,OAAA,EAAA;YAJI;cACE;UACJ;IAET,QAAQ,UAAU"}
@@ -0,0 +1,66 @@
1
+ import { TelemetryManager } from "../telemetry/telemetry-manager.js";
2
+ import "../telemetry/index.js";
3
+ import { CacheManager } from "../cache/index.js";
4
+
5
+ //#region src/core/appkit.ts
6
+ var AppKit = class AppKit {
7
+ static {
8
+ this._instance = null;
9
+ }
10
+ constructor(config) {
11
+ this.pluginInstances = {};
12
+ this.setupPromises = [];
13
+ const { plugins, ...globalConfig } = config;
14
+ const pluginEntries = Object.entries(plugins);
15
+ const corePlugins = pluginEntries.filter(([_, p]) => {
16
+ return (p?.plugin?.phase ?? "normal") === "core";
17
+ });
18
+ const normalPlugins = pluginEntries.filter(([_, p]) => (p?.plugin?.phase ?? "normal") === "normal");
19
+ const deferredPlugins = pluginEntries.filter(([_, p]) => (p?.plugin?.phase ?? "normal") === "deferred");
20
+ for (const [name, pluginData] of corePlugins) if (pluginData) this.createAndRegisterPlugin(globalConfig, name, pluginData);
21
+ for (const [name, pluginData] of normalPlugins) if (pluginData) this.createAndRegisterPlugin(globalConfig, name, pluginData);
22
+ for (const [name, pluginData] of deferredPlugins) if (pluginData) this.createAndRegisterPlugin(globalConfig, name, pluginData, { plugins: this.pluginInstances });
23
+ }
24
+ createAndRegisterPlugin(config, name, pluginData, extraData) {
25
+ const { plugin: Plugin, config: pluginConfig } = pluginData;
26
+ const pluginInstance = new Plugin({
27
+ ...config,
28
+ ...Plugin.DEFAULT_CONFIG,
29
+ ...pluginConfig,
30
+ name,
31
+ ...extraData
32
+ });
33
+ this.pluginInstances[name] = pluginInstance;
34
+ pluginInstance.validateEnv();
35
+ this.setupPromises.push(pluginInstance.setup());
36
+ Object.defineProperty(this, name, {
37
+ get() {
38
+ return this.pluginInstances[name];
39
+ },
40
+ enumerable: true
41
+ });
42
+ }
43
+ static async _createApp(config = {}) {
44
+ TelemetryManager.initialize(config?.telemetry);
45
+ await CacheManager.getInstance(config?.cache);
46
+ const rawPlugins = config.plugins;
47
+ AppKit._instance = new AppKit({ plugins: AppKit.preparePlugins(rawPlugins) });
48
+ await Promise.all(AppKit._instance.setupPromises);
49
+ return AppKit._instance;
50
+ }
51
+ static preparePlugins(plugins) {
52
+ const result = {};
53
+ for (const currentPlugin of plugins) result[currentPlugin.name] = {
54
+ plugin: currentPlugin.plugin,
55
+ config: currentPlugin.config
56
+ };
57
+ return result;
58
+ }
59
+ };
60
+ async function createApp(config = {}) {
61
+ return AppKit._createApp(config);
62
+ }
63
+
64
+ //#endregion
65
+ export { createApp };
66
+ //# sourceMappingURL=appkit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appkit.js","names":["result: InputPluginMap"],"sources":["../../src/core/appkit.ts"],"sourcesContent":["import type {\n BasePlugin,\n CacheConfig,\n InputPluginMap,\n OptionalConfigPluginDef,\n PluginConstructor,\n PluginData,\n PluginMap,\n} from \"shared\";\nimport { CacheManager } from \"../cache\";\nimport type { TelemetryConfig } from \"../telemetry\";\nimport { TelemetryManager } from \"../telemetry\";\n\nexport class AppKit<TPlugins extends InputPluginMap> {\n private static _instance: AppKit<InputPluginMap> | null = null;\n private pluginInstances: Record<string, BasePlugin> = {};\n private setupPromises: Promise<void>[] = [];\n\n private constructor(config: { plugins: TPlugins }) {\n const { plugins, ...globalConfig } = config;\n\n const pluginEntries = Object.entries(plugins);\n\n const corePlugins = pluginEntries.filter(([_, p]) => {\n return (p?.plugin?.phase ?? \"normal\") === \"core\";\n });\n const normalPlugins = pluginEntries.filter(\n ([_, p]) => (p?.plugin?.phase ?? \"normal\") === \"normal\",\n );\n const deferredPlugins = pluginEntries.filter(\n ([_, p]) => (p?.plugin?.phase ?? \"normal\") === \"deferred\",\n );\n\n for (const [name, pluginData] of corePlugins) {\n if (pluginData) {\n this.createAndRegisterPlugin(globalConfig, name, pluginData);\n }\n }\n\n for (const [name, pluginData] of normalPlugins) {\n if (pluginData) {\n this.createAndRegisterPlugin(globalConfig, name, pluginData);\n }\n }\n\n for (const [name, pluginData] of deferredPlugins) {\n if (pluginData) {\n this.createAndRegisterPlugin(globalConfig, name, pluginData, {\n plugins: this.pluginInstances,\n });\n }\n }\n }\n\n private createAndRegisterPlugin<T extends PluginConstructor>(\n config: Omit<{ plugins: TPlugins }, \"plugins\">,\n name: string,\n pluginData: OptionalConfigPluginDef<T>,\n extraData?: Record<string, unknown>,\n ) {\n const { plugin: Plugin, config: pluginConfig } = pluginData;\n const baseConfig = {\n ...config,\n ...Plugin.DEFAULT_CONFIG,\n ...pluginConfig,\n name,\n ...extraData,\n };\n const pluginInstance = new Plugin(baseConfig);\n\n this.pluginInstances[name] = pluginInstance;\n\n pluginInstance.validateEnv();\n\n this.setupPromises.push(pluginInstance.setup());\n\n Object.defineProperty(this, name, {\n get() {\n return this.pluginInstances[name];\n },\n enumerable: true,\n });\n }\n\n static async _createApp<\n T extends PluginData<PluginConstructor, unknown, string>[],\n >(\n config: {\n plugins?: T;\n telemetry?: TelemetryConfig;\n cache?: CacheConfig;\n } = {},\n ): Promise<PluginMap<T>> {\n TelemetryManager.initialize(config?.telemetry);\n await CacheManager.getInstance(config?.cache);\n\n const rawPlugins = config.plugins as T;\n const preparedPlugins = AppKit.preparePlugins(rawPlugins);\n const mergedConfig = {\n plugins: preparedPlugins,\n };\n\n AppKit._instance = new AppKit(mergedConfig);\n\n await Promise.all(AppKit._instance.setupPromises);\n\n return AppKit._instance as unknown as PluginMap<T>;\n }\n\n private static preparePlugins(\n plugins: PluginData<PluginConstructor, unknown, string>[],\n ) {\n const result: InputPluginMap = {};\n for (const currentPlugin of plugins) {\n result[currentPlugin.name] = {\n plugin: currentPlugin.plugin,\n config: currentPlugin.config as Record<string, unknown>,\n };\n }\n return result;\n }\n}\n\nexport async function createApp<\n T extends PluginData<PluginConstructor, unknown, string>[],\n>(\n config: {\n plugins?: T;\n telemetry?: TelemetryConfig;\n cache?: CacheConfig;\n } = {},\n): Promise<PluginMap<T>> {\n return AppKit._createApp(config);\n}\n"],"mappings":";;;;;AAaA,IAAa,SAAb,MAAa,OAAwC;;mBACO;;CAI1D,AAAQ,YAAY,QAA+B;yBAHG,EAAE;uBACf,EAAE;EAGzC,MAAM,EAAE,SAAS,GAAG,iBAAiB;EAErC,MAAM,gBAAgB,OAAO,QAAQ,QAAQ;EAE7C,MAAM,cAAc,cAAc,QAAQ,CAAC,GAAG,OAAO;AACnD,WAAQ,GAAG,QAAQ,SAAS,cAAc;IAC1C;EACF,MAAM,gBAAgB,cAAc,QACjC,CAAC,GAAG,QAAQ,GAAG,QAAQ,SAAS,cAAc,SAChD;EACD,MAAM,kBAAkB,cAAc,QACnC,CAAC,GAAG,QAAQ,GAAG,QAAQ,SAAS,cAAc,WAChD;AAED,OAAK,MAAM,CAAC,MAAM,eAAe,YAC/B,KAAI,WACF,MAAK,wBAAwB,cAAc,MAAM,WAAW;AAIhE,OAAK,MAAM,CAAC,MAAM,eAAe,cAC/B,KAAI,WACF,MAAK,wBAAwB,cAAc,MAAM,WAAW;AAIhE,OAAK,MAAM,CAAC,MAAM,eAAe,gBAC/B,KAAI,WACF,MAAK,wBAAwB,cAAc,MAAM,YAAY,EAC3D,SAAS,KAAK,iBACf,CAAC;;CAKR,AAAQ,wBACN,QACA,MACA,YACA,WACA;EACA,MAAM,EAAE,QAAQ,QAAQ,QAAQ,iBAAiB;EAQjD,MAAM,iBAAiB,IAAI,OAPR;GACjB,GAAG;GACH,GAAG,OAAO;GACV,GAAG;GACH;GACA,GAAG;GACJ,CAC4C;AAE7C,OAAK,gBAAgB,QAAQ;AAE7B,iBAAe,aAAa;AAE5B,OAAK,cAAc,KAAK,eAAe,OAAO,CAAC;AAE/C,SAAO,eAAe,MAAM,MAAM;GAChC,MAAM;AACJ,WAAO,KAAK,gBAAgB;;GAE9B,YAAY;GACb,CAAC;;CAGJ,aAAa,WAGX,SAII,EAAE,EACiB;AACvB,mBAAiB,WAAW,QAAQ,UAAU;AAC9C,QAAM,aAAa,YAAY,QAAQ,MAAM;EAE7C,MAAM,aAAa,OAAO;AAM1B,SAAO,YAAY,IAAI,OAJF,EACnB,SAFsB,OAAO,eAAe,WAAW,EAGxD,CAE0C;AAE3C,QAAM,QAAQ,IAAI,OAAO,UAAU,cAAc;AAEjD,SAAO,OAAO;;CAGhB,OAAe,eACb,SACA;EACA,MAAMA,SAAyB,EAAE;AACjC,OAAK,MAAM,iBAAiB,QAC1B,QAAO,cAAc,QAAQ;GAC3B,QAAQ,cAAc;GACtB,QAAQ,cAAc;GACvB;AAEH,SAAO;;;AAIX,eAAsB,UAGpB,SAII,EAAE,EACiB;AACvB,QAAO,OAAO,WAAW,OAAO"}
@@ -0,0 +1,3 @@
1
+ import { createApp } from "./appkit.js";
2
+
3
+ export { };
@@ -0,0 +1,15 @@
1
+ import { BasePluginConfig, IAppRouter } from "./shared/src/plugin.js";
2
+ import { StreamExecutionSettings } from "./shared/src/execute.js";
3
+ import { SQLTypeMarker } from "./shared/src/sql/types.js";
4
+ import { isSQLTypeMarker, sql } from "./shared/src/sql/helpers.js";
5
+ import { CacheManager } from "./cache/index.js";
6
+ import { ITelemetry } from "./telemetry/types.js";
7
+ import { Counter, Histogram, SeverityNumber, Span, SpanStatusCode } from "./telemetry/index.js";
8
+ import { Plugin } from "./plugin/plugin.js";
9
+ import { toPlugin } from "./plugin/to-plugin.js";
10
+ import { analytics } from "./analytics/analytics.js";
11
+ import { createApp } from "./core/appkit.js";
12
+ import { server } from "./server/index.js";
13
+ import { appKitTypesPlugin } from "./type-generator/vite-plugin.js";
14
+ import { getRequestContext } from "./utils/databricks-client-middleware.js";
15
+ export { type BasePluginConfig, CacheManager, type Counter, type Histogram, type IAppRouter, type ITelemetry, Plugin, type SQLTypeMarker, SeverityNumber, type Span, SpanStatusCode, type StreamExecutionSettings, analytics, appKitTypesPlugin, createApp, getRequestContext, isSQLTypeMarker, server, sql, toPlugin };
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ import { isSQLTypeMarker, sql } from "./shared/src/sql/helpers.js";
2
+ import { SeverityNumber, SpanStatusCode } from "./telemetry/index.js";
3
+ import { getRequestContext } from "./utils/databricks-client-middleware.js";
4
+ import { init_utils } from "./utils/index.js";
5
+ import { CacheManager } from "./cache/index.js";
6
+ import { Plugin } from "./plugin/plugin.js";
7
+ import { toPlugin } from "./plugin/to-plugin.js";
8
+ import "./plugin/index.js";
9
+ import { analytics } from "./analytics/analytics.js";
10
+ import "./analytics/index.js";
11
+ import { createApp } from "./core/appkit.js";
12
+ import "./core/index.js";
13
+ import { appKitTypesPlugin } from "./type-generator/vite-plugin.js";
14
+ import { server } from "./server/index.js";
15
+
16
+ //#region src/index.ts
17
+ init_utils();
18
+
19
+ //#endregion
20
+ export { CacheManager, Plugin, SeverityNumber, SpanStatusCode, analytics, appKitTypesPlugin, createApp, getRequestContext, isSQLTypeMarker, server, sql, toPlugin };
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type {\n BasePluginConfig,\n IAppRouter,\n SQLTypeMarker,\n StreamExecutionSettings,\n} from \"shared\";\nexport {\n isSQLTypeMarker,\n sql,\n} from \"shared\";\nexport { analytics } from \"./analytics\";\nexport { CacheManager } from \"./cache\";\nexport { createApp } from \"./core\";\nexport { Plugin, toPlugin } from \"./plugin\";\nexport { server } from \"./server\";\nexport type { ITelemetry } from \"./telemetry\";\nexport {\n type Counter,\n type Histogram,\n SeverityNumber,\n type Span,\n SpanStatusCode,\n} from \"./telemetry\";\nexport { appKitTypesPlugin } from \"./type-generator/vite-plugin\";\nexport { getRequestContext } from \"./utils\";\n"],"mappings":";;;;;;;;;;;;;;;;YAwB4C"}
@@ -0,0 +1,20 @@
1
+ import { TunnelConnection } from "../shared/src/tunnel.js";
2
+ import * as express0 from "express";
3
+
4
+ //#region src/plugin/dev-reader.d.ts
5
+ type TunnelConnectionGetter = (req: express0.Request) => TunnelConnection | null;
6
+ /**
7
+ * This class is used to read files from the local filesystem in dev mode
8
+ * through the WebSocket tunnel.
9
+ */
10
+ declare class DevFileReader {
11
+ private static instance;
12
+ private getTunnelForRequest;
13
+ private constructor();
14
+ static getInstance(): DevFileReader;
15
+ registerTunnelGetter(getter: TunnelConnectionGetter): void;
16
+ readFile(filePath: string, req: express0.Request): Promise<string>;
17
+ }
18
+ //#endregion
19
+ export { DevFileReader };
20
+ //# sourceMappingURL=dev-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-reader.d.ts","names":[],"sources":["../../src/plugin/dev-reader.ts"],"sourcesContent":[],"mappings":";;;;KAIK,sBAAA,SAAsB,QAAA,CACF,YACpB;;;AAL0C;;AAGpB,cAQd,aAAA,CAPY;iBACpB,QAAA;EAAgB,QAAA,mBAAA;EAMR,QAAA,WAAa,CAAA;EAAA,OAAA,WAAA,CAAA,CAAA,EAMF,aANE;sBAMF,CAAA,MAAA,EA+BO,sBA/BP,CAAA,EAAA,IAAA;UA+BO,CAAA,QAAA,EAAA,MAAA,EAAA,GAAA,EAAsB,QAAA,CAM1B,OANI,CAAA,EAO1B,OAP0B,CAAA,MAAA,CAAA"}
@@ -0,0 +1,63 @@
1
+ import { isRemoteTunnelAllowedByEnv } from "../server/remote-tunnel/gate.js";
2
+ import { randomUUID } from "node:crypto";
3
+
4
+ //#region src/plugin/dev-reader.ts
5
+ /**
6
+ * This class is used to read files from the local filesystem in dev mode
7
+ * through the WebSocket tunnel.
8
+ */
9
+ var DevFileReader = class DevFileReader {
10
+ static {
11
+ this.instance = null;
12
+ }
13
+ constructor() {
14
+ this.getTunnelForRequest = null;
15
+ }
16
+ static getInstance() {
17
+ if (!DevFileReader.instance) DevFileReader.instance = new Proxy(new DevFileReader(), {
18
+ get(target, prop, receiver) {
19
+ if (isRemoteTunnelAllowedByEnv()) return Reflect.get(target, prop, receiver);
20
+ const value = Reflect.get(target, prop, receiver);
21
+ if (typeof value === "function") return function noop() {
22
+ console.info(`Noop: ${String(prop)} (remote server disabled)`);
23
+ return Promise.resolve("");
24
+ };
25
+ return value;
26
+ },
27
+ set(target, prop, value, receiver) {
28
+ return Reflect.set(target, prop, value, receiver);
29
+ }
30
+ });
31
+ return DevFileReader.instance;
32
+ }
33
+ registerTunnelGetter(getter) {
34
+ this.getTunnelForRequest = getter;
35
+ }
36
+ async readFile(filePath, req) {
37
+ if (!this.getTunnelForRequest) throw new Error("Tunnel getter not registered for DevFileReader singleton");
38
+ const tunnel = this.getTunnelForRequest(req);
39
+ if (!tunnel) throw new Error("No tunnel connection available for file read");
40
+ const { ws, pendingFileReads } = tunnel;
41
+ const requestId = randomUUID();
42
+ return new Promise((resolve, reject) => {
43
+ const timeout = setTimeout(() => {
44
+ pendingFileReads.delete(requestId);
45
+ reject(/* @__PURE__ */ new Error(`File read timeout: ${filePath}`));
46
+ }, 1e4);
47
+ pendingFileReads.set(requestId, {
48
+ resolve,
49
+ reject,
50
+ timeout
51
+ });
52
+ ws.send(JSON.stringify({
53
+ type: "file:read",
54
+ requestId,
55
+ path: filePath
56
+ }));
57
+ });
58
+ }
59
+ };
60
+
61
+ //#endregion
62
+ export { DevFileReader };
63
+ //# sourceMappingURL=dev-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-reader.js","names":[],"sources":["../../src/plugin/dev-reader.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { TunnelConnection } from \"shared\";\nimport { isRemoteTunnelAllowedByEnv } from \"@/server/remote-tunnel/gate\";\n\ntype TunnelConnectionGetter = (\n req: import(\"express\").Request,\n) => TunnelConnection | null;\n\n/**\n * This class is used to read files from the local filesystem in dev mode\n * through the WebSocket tunnel.\n */\nexport class DevFileReader {\n private static instance: DevFileReader | null = null;\n private getTunnelForRequest: TunnelConnectionGetter | null = null;\n\n private constructor() {}\n\n static getInstance(): DevFileReader {\n if (!DevFileReader.instance) {\n DevFileReader.instance = new Proxy(new DevFileReader(), {\n /**\n * We proxy the reader to return a noop function if the remote server is disabled.\n */\n get(target, prop, receiver) {\n if (isRemoteTunnelAllowedByEnv()) {\n return Reflect.get(target, prop, receiver);\n }\n\n const value = Reflect.get(target, prop, receiver);\n\n if (typeof value === \"function\") {\n return function noop() {\n console.info(`Noop: ${String(prop)} (remote server disabled)`);\n return Promise.resolve(\"\");\n };\n }\n\n return value;\n },\n set(target, prop, value, receiver) {\n return Reflect.set(target, prop, value, receiver);\n },\n });\n }\n\n return DevFileReader.instance;\n }\n\n registerTunnelGetter(getter: TunnelConnectionGetter) {\n this.getTunnelForRequest = getter;\n }\n\n async readFile(\n filePath: string,\n req: import(\"express\").Request,\n ): Promise<string> {\n if (!this.getTunnelForRequest) {\n throw new Error(\n \"Tunnel getter not registered for DevFileReader singleton\",\n );\n }\n const tunnel = this.getTunnelForRequest(req);\n\n if (!tunnel) {\n throw new Error(\"No tunnel connection available for file read\");\n }\n\n const { ws, pendingFileReads } = tunnel;\n const requestId = randomUUID();\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n pendingFileReads.delete(requestId);\n reject(new Error(`File read timeout: ${filePath}`));\n }, 10000);\n\n pendingFileReads.set(requestId, { resolve, reject, timeout });\n\n ws.send(\n JSON.stringify({\n type: \"file:read\",\n requestId,\n path: filePath,\n }),\n );\n });\n }\n}\n"],"mappings":";;;;;;;;AAYA,IAAa,gBAAb,MAAa,cAAc;;kBACuB;;CAGhD,AAAQ,cAAc;6BAFuC;;CAI7D,OAAO,cAA6B;AAClC,MAAI,CAAC,cAAc,SACjB,eAAc,WAAW,IAAI,MAAM,IAAI,eAAe,EAAE;GAItD,IAAI,QAAQ,MAAM,UAAU;AAC1B,QAAI,4BAA4B,CAC9B,QAAO,QAAQ,IAAI,QAAQ,MAAM,SAAS;IAG5C,MAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,SAAS;AAEjD,QAAI,OAAO,UAAU,WACnB,QAAO,SAAS,OAAO;AACrB,aAAQ,KAAK,SAAS,OAAO,KAAK,CAAC,2BAA2B;AAC9D,YAAO,QAAQ,QAAQ,GAAG;;AAI9B,WAAO;;GAET,IAAI,QAAQ,MAAM,OAAO,UAAU;AACjC,WAAO,QAAQ,IAAI,QAAQ,MAAM,OAAO,SAAS;;GAEpD,CAAC;AAGJ,SAAO,cAAc;;CAGvB,qBAAqB,QAAgC;AACnD,OAAK,sBAAsB;;CAG7B,MAAM,SACJ,UACA,KACiB;AACjB,MAAI,CAAC,KAAK,oBACR,OAAM,IAAI,MACR,2DACD;EAEH,MAAM,SAAS,KAAK,oBAAoB,IAAI;AAE5C,MAAI,CAAC,OACH,OAAM,IAAI,MAAM,+CAA+C;EAGjE,MAAM,EAAE,IAAI,qBAAqB;EACjC,MAAM,YAAY,YAAY;AAE9B,SAAO,IAAI,SAAS,SAAS,WAAW;GACtC,MAAM,UAAU,iBAAiB;AAC/B,qBAAiB,OAAO,UAAU;AAClC,2BAAO,IAAI,MAAM,sBAAsB,WAAW,CAAC;MAClD,IAAM;AAET,oBAAiB,IAAI,WAAW;IAAE;IAAS;IAAQ;IAAS,CAAC;AAE7D,MAAG,KACD,KAAK,UAAU;IACb,MAAM;IACN;IACA,MAAM;IACP,CAAC,CACH;IACD"}
@@ -0,0 +1,4 @@
1
+ import { Plugin } from "./plugin.js";
2
+ import { toPlugin } from "./to-plugin.js";
3
+
4
+ export { };
@@ -0,0 +1,15 @@
1
+ //#region src/plugin/interceptors/cache.ts
2
+ var CacheInterceptor = class {
3
+ constructor(cacheManager, config) {
4
+ this.cacheManager = cacheManager;
5
+ this.config = config;
6
+ }
7
+ async intercept(fn, context) {
8
+ if (!this.config.enabled || !this.config.cacheKey?.length) return fn();
9
+ return this.cacheManager.getOrExecute(this.config.cacheKey, fn, context.userKey, { ttl: this.config.ttl });
10
+ }
11
+ };
12
+
13
+ //#endregion
14
+ export { CacheInterceptor };
15
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","names":["cacheManager: CacheManager","config: CacheConfig"],"sources":["../../../src/plugin/interceptors/cache.ts"],"sourcesContent":["import type { CacheManager } from \"../../cache\";\nimport type { CacheConfig } from \"shared\";\nimport type { ExecutionContext, ExecutionInterceptor } from \"./types\";\n\n// interceptor to handle caching logic\nexport class CacheInterceptor implements ExecutionInterceptor {\n constructor(\n private cacheManager: CacheManager,\n private config: CacheConfig,\n ) {}\n\n async intercept<T>(\n fn: () => Promise<T>,\n context: ExecutionContext,\n ): Promise<T> {\n // if cache disabled, ignore\n if (!this.config.enabled || !this.config.cacheKey?.length) {\n return fn();\n }\n\n return this.cacheManager.getOrExecute(\n this.config.cacheKey,\n fn,\n context.userKey,\n { ttl: this.config.ttl },\n );\n }\n}\n"],"mappings":";AAKA,IAAa,mBAAb,MAA8D;CAC5D,YACE,AAAQA,cACR,AAAQC,QACR;EAFQ;EACA;;CAGV,MAAM,UACJ,IACA,SACY;AAEZ,MAAI,CAAC,KAAK,OAAO,WAAW,CAAC,KAAK,OAAO,UAAU,OACjD,QAAO,IAAI;AAGb,SAAO,KAAK,aAAa,aACvB,KAAK,OAAO,UACZ,IACA,QAAQ,SACR,EAAE,KAAK,KAAK,OAAO,KAAK,CACzB"}