duckpond 0.1.0
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/LICENSE +21 -0
- package/README.md +453 -0
- package/dist/DuckPond.d.mts +94 -0
- package/dist/DuckPond.d.ts +94 -0
- package/dist/DuckPond.js +2 -0
- package/dist/DuckPond.js.map +1 -0
- package/dist/DuckPond.mjs +2 -0
- package/dist/DuckPond.mjs.map +1 -0
- package/dist/cache/LRUCache.d.mts +75 -0
- package/dist/cache/LRUCache.d.ts +75 -0
- package/dist/cache/LRUCache.js +2 -0
- package/dist/cache/LRUCache.js.map +1 -0
- package/dist/cache/LRUCache.mjs +2 -0
- package/dist/cache/LRUCache.mjs.map +1 -0
- package/dist/chunk-24M54WUC.mjs +2 -0
- package/dist/chunk-24M54WUC.mjs.map +1 -0
- package/dist/chunk-4NKFJCEP.mjs +27 -0
- package/dist/chunk-4NKFJCEP.mjs.map +1 -0
- package/dist/chunk-5XGN7UAV.js +2 -0
- package/dist/chunk-5XGN7UAV.js.map +1 -0
- package/dist/chunk-DTZ5B6AO.mjs +2 -0
- package/dist/chunk-DTZ5B6AO.mjs.map +1 -0
- package/dist/chunk-E5ZZH3QB.js +2 -0
- package/dist/chunk-E5ZZH3QB.js.map +1 -0
- package/dist/chunk-J2OQ62DV.js +2 -0
- package/dist/chunk-J2OQ62DV.js.map +1 -0
- package/dist/chunk-MZTKR3LR.js +3 -0
- package/dist/chunk-MZTKR3LR.js.map +1 -0
- package/dist/chunk-PCQEPXO3.mjs +3 -0
- package/dist/chunk-PCQEPXO3.mjs.map +1 -0
- package/dist/chunk-Q6UFPTQC.js +2 -0
- package/dist/chunk-Q6UFPTQC.js.map +1 -0
- package/dist/chunk-SZJXSB7U.mjs +2 -0
- package/dist/chunk-SZJXSB7U.mjs.map +1 -0
- package/dist/chunk-TLGHSO3F.js +27 -0
- package/dist/chunk-TLGHSO3F.js.map +1 -0
- package/dist/chunk-V57JCP3U.mjs +2 -0
- package/dist/chunk-V57JCP3U.mjs.map +1 -0
- package/dist/index.d.mts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types.d.mts +182 -0
- package/dist/types.d.ts +182 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +2 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils/errors.d.mts +40 -0
- package/dist/utils/errors.d.ts +40 -0
- package/dist/utils/errors.js +2 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/errors.mjs +2 -0
- package/dist/utils/errors.mjs.map +1 -0
- package/dist/utils/logger.d.mts +25 -0
- package/dist/utils/logger.d.ts +25 -0
- package/dist/utils/logger.js +2 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/logger.mjs +2 -0
- package/dist/utils/logger.mjs.map +1 -0
- package/package.json +80 -0
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { DuckDBConnection } from '@duckdb/node-api';
|
|
2
|
+
import { Either } from 'functype/either';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for DuckPond manager
|
|
6
|
+
*/
|
|
7
|
+
interface DuckPondConfig {
|
|
8
|
+
r2?: {
|
|
9
|
+
accountId: string;
|
|
10
|
+
accessKeyId: string;
|
|
11
|
+
secretAccessKey: string;
|
|
12
|
+
bucket: string;
|
|
13
|
+
};
|
|
14
|
+
s3?: {
|
|
15
|
+
region: string;
|
|
16
|
+
accessKeyId: string;
|
|
17
|
+
secretAccessKey: string;
|
|
18
|
+
bucket: string;
|
|
19
|
+
endpoint?: string;
|
|
20
|
+
};
|
|
21
|
+
memoryLimit?: string;
|
|
22
|
+
threads?: number;
|
|
23
|
+
tempDir?: string;
|
|
24
|
+
maxActiveUsers?: number;
|
|
25
|
+
evictionTimeout?: number;
|
|
26
|
+
cacheType?: "disk" | "memory" | "noop";
|
|
27
|
+
cacheDir?: string;
|
|
28
|
+
strategy?: "parquet" | "duckdb" | "hybrid";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Represents an active user database connection
|
|
32
|
+
*/
|
|
33
|
+
interface UserDatabase {
|
|
34
|
+
userId: string;
|
|
35
|
+
connection: DuckDBConnection;
|
|
36
|
+
lastAccess: Date;
|
|
37
|
+
attached: boolean;
|
|
38
|
+
memoryUsage?: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Statistics about a user's database
|
|
42
|
+
*/
|
|
43
|
+
interface UserStats {
|
|
44
|
+
userId: string;
|
|
45
|
+
attached: boolean;
|
|
46
|
+
lastAccess: Date;
|
|
47
|
+
memoryUsage: number;
|
|
48
|
+
storageUsage: number;
|
|
49
|
+
queryCount: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Database schema information
|
|
53
|
+
*/
|
|
54
|
+
interface Schema {
|
|
55
|
+
tables: TableSchema[];
|
|
56
|
+
}
|
|
57
|
+
interface TableSchema {
|
|
58
|
+
name: string;
|
|
59
|
+
columns: ColumnSchema[];
|
|
60
|
+
rowCount?: number;
|
|
61
|
+
}
|
|
62
|
+
interface ColumnSchema {
|
|
63
|
+
name: string;
|
|
64
|
+
type: string;
|
|
65
|
+
nullable: boolean;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Options for creating a new user
|
|
69
|
+
*/
|
|
70
|
+
interface CreateUserOptions {
|
|
71
|
+
template?: string;
|
|
72
|
+
initialData?: Record<string, unknown[]>;
|
|
73
|
+
metadata?: Record<string, unknown>;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Storage usage statistics
|
|
77
|
+
*/
|
|
78
|
+
interface StorageStats {
|
|
79
|
+
totalSize: number;
|
|
80
|
+
fileCount: number;
|
|
81
|
+
lastModified: Date;
|
|
82
|
+
files?: FileInfo[];
|
|
83
|
+
}
|
|
84
|
+
interface FileInfo {
|
|
85
|
+
path: string;
|
|
86
|
+
size: number;
|
|
87
|
+
modified: Date;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Query result with metadata
|
|
91
|
+
*/
|
|
92
|
+
interface QueryResult<T = unknown> {
|
|
93
|
+
rows: T[];
|
|
94
|
+
rowCount: number;
|
|
95
|
+
executionTime: number;
|
|
96
|
+
columns: string[];
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Metrics for monitoring
|
|
100
|
+
*/
|
|
101
|
+
interface DuckPondMetrics {
|
|
102
|
+
activeUsers: number;
|
|
103
|
+
totalQueries: number;
|
|
104
|
+
avgQueryTime: number;
|
|
105
|
+
cacheHitRate: number;
|
|
106
|
+
memoryUsage: number;
|
|
107
|
+
storageUsage: number;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Events emitted by DuckPond
|
|
111
|
+
*/
|
|
112
|
+
type DuckPondEvent = {
|
|
113
|
+
type: "user:attached";
|
|
114
|
+
userId: string;
|
|
115
|
+
timestamp: Date;
|
|
116
|
+
} | {
|
|
117
|
+
type: "user:detached";
|
|
118
|
+
userId: string;
|
|
119
|
+
reason: "eviction" | "manual";
|
|
120
|
+
timestamp: Date;
|
|
121
|
+
} | {
|
|
122
|
+
type: "query:executed";
|
|
123
|
+
userId: string;
|
|
124
|
+
duration: number;
|
|
125
|
+
timestamp: Date;
|
|
126
|
+
} | {
|
|
127
|
+
type: "query:failed";
|
|
128
|
+
userId: string;
|
|
129
|
+
error: string;
|
|
130
|
+
timestamp: Date;
|
|
131
|
+
} | {
|
|
132
|
+
type: "cache:hit";
|
|
133
|
+
userId: string;
|
|
134
|
+
} | {
|
|
135
|
+
type: "cache:miss";
|
|
136
|
+
userId: string;
|
|
137
|
+
} | {
|
|
138
|
+
type: "error";
|
|
139
|
+
error: Error;
|
|
140
|
+
timestamp: Date;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Type-safe result types using functype Either
|
|
144
|
+
*/
|
|
145
|
+
type DuckPondResult<T> = Either<DuckPondError, T>;
|
|
146
|
+
type AsyncDuckPondResult<T> = Promise<Either<DuckPondError, T>>;
|
|
147
|
+
/**
|
|
148
|
+
* Error types
|
|
149
|
+
*/
|
|
150
|
+
interface DuckPondError {
|
|
151
|
+
code: ErrorCode;
|
|
152
|
+
message: string;
|
|
153
|
+
cause?: Error;
|
|
154
|
+
context?: Record<string, unknown>;
|
|
155
|
+
}
|
|
156
|
+
declare enum ErrorCode {
|
|
157
|
+
CONNECTION_FAILED = "CONNECTION_FAILED",
|
|
158
|
+
CONNECTION_TIMEOUT = "CONNECTION_TIMEOUT",
|
|
159
|
+
R2_CONNECTION_ERROR = "R2_CONNECTION_ERROR",
|
|
160
|
+
S3_CONNECTION_ERROR = "S3_CONNECTION_ERROR",
|
|
161
|
+
USER_NOT_FOUND = "USER_NOT_FOUND",
|
|
162
|
+
USER_ALREADY_EXISTS = "USER_ALREADY_EXISTS",
|
|
163
|
+
USER_NOT_ATTACHED = "USER_NOT_ATTACHED",
|
|
164
|
+
QUERY_EXECUTION_ERROR = "QUERY_EXECUTION_ERROR",
|
|
165
|
+
QUERY_TIMEOUT = "QUERY_TIMEOUT",
|
|
166
|
+
INVALID_SQL = "INVALID_SQL",
|
|
167
|
+
MEMORY_LIMIT_EXCEEDED = "MEMORY_LIMIT_EXCEEDED",
|
|
168
|
+
STORAGE_ERROR = "STORAGE_ERROR",
|
|
169
|
+
STORAGE_QUOTA_EXCEEDED = "STORAGE_QUOTA_EXCEEDED",
|
|
170
|
+
INVALID_CONFIG = "INVALID_CONFIG",
|
|
171
|
+
NOT_INITIALIZED = "NOT_INITIALIZED",
|
|
172
|
+
UNKNOWN_ERROR = "UNKNOWN_ERROR"
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Configuration with defaults applied
|
|
176
|
+
*/
|
|
177
|
+
type ResolvedConfig = Required<Omit<DuckPondConfig, "r2" | "s3"> & {
|
|
178
|
+
r2: DuckPondConfig["r2"];
|
|
179
|
+
s3: DuckPondConfig["s3"];
|
|
180
|
+
}>;
|
|
181
|
+
|
|
182
|
+
export { type AsyncDuckPondResult, type ColumnSchema, type CreateUserOptions, type DuckPondConfig, type DuckPondError, type DuckPondEvent, type DuckPondMetrics, type DuckPondResult, ErrorCode, type FileInfo, type QueryResult, type ResolvedConfig, type Schema, type StorageStats, type TableSchema, type UserDatabase, type UserStats };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { DuckDBConnection } from '@duckdb/node-api';
|
|
2
|
+
import { Either } from 'functype/either';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for DuckPond manager
|
|
6
|
+
*/
|
|
7
|
+
interface DuckPondConfig {
|
|
8
|
+
r2?: {
|
|
9
|
+
accountId: string;
|
|
10
|
+
accessKeyId: string;
|
|
11
|
+
secretAccessKey: string;
|
|
12
|
+
bucket: string;
|
|
13
|
+
};
|
|
14
|
+
s3?: {
|
|
15
|
+
region: string;
|
|
16
|
+
accessKeyId: string;
|
|
17
|
+
secretAccessKey: string;
|
|
18
|
+
bucket: string;
|
|
19
|
+
endpoint?: string;
|
|
20
|
+
};
|
|
21
|
+
memoryLimit?: string;
|
|
22
|
+
threads?: number;
|
|
23
|
+
tempDir?: string;
|
|
24
|
+
maxActiveUsers?: number;
|
|
25
|
+
evictionTimeout?: number;
|
|
26
|
+
cacheType?: "disk" | "memory" | "noop";
|
|
27
|
+
cacheDir?: string;
|
|
28
|
+
strategy?: "parquet" | "duckdb" | "hybrid";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Represents an active user database connection
|
|
32
|
+
*/
|
|
33
|
+
interface UserDatabase {
|
|
34
|
+
userId: string;
|
|
35
|
+
connection: DuckDBConnection;
|
|
36
|
+
lastAccess: Date;
|
|
37
|
+
attached: boolean;
|
|
38
|
+
memoryUsage?: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Statistics about a user's database
|
|
42
|
+
*/
|
|
43
|
+
interface UserStats {
|
|
44
|
+
userId: string;
|
|
45
|
+
attached: boolean;
|
|
46
|
+
lastAccess: Date;
|
|
47
|
+
memoryUsage: number;
|
|
48
|
+
storageUsage: number;
|
|
49
|
+
queryCount: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Database schema information
|
|
53
|
+
*/
|
|
54
|
+
interface Schema {
|
|
55
|
+
tables: TableSchema[];
|
|
56
|
+
}
|
|
57
|
+
interface TableSchema {
|
|
58
|
+
name: string;
|
|
59
|
+
columns: ColumnSchema[];
|
|
60
|
+
rowCount?: number;
|
|
61
|
+
}
|
|
62
|
+
interface ColumnSchema {
|
|
63
|
+
name: string;
|
|
64
|
+
type: string;
|
|
65
|
+
nullable: boolean;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Options for creating a new user
|
|
69
|
+
*/
|
|
70
|
+
interface CreateUserOptions {
|
|
71
|
+
template?: string;
|
|
72
|
+
initialData?: Record<string, unknown[]>;
|
|
73
|
+
metadata?: Record<string, unknown>;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Storage usage statistics
|
|
77
|
+
*/
|
|
78
|
+
interface StorageStats {
|
|
79
|
+
totalSize: number;
|
|
80
|
+
fileCount: number;
|
|
81
|
+
lastModified: Date;
|
|
82
|
+
files?: FileInfo[];
|
|
83
|
+
}
|
|
84
|
+
interface FileInfo {
|
|
85
|
+
path: string;
|
|
86
|
+
size: number;
|
|
87
|
+
modified: Date;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Query result with metadata
|
|
91
|
+
*/
|
|
92
|
+
interface QueryResult<T = unknown> {
|
|
93
|
+
rows: T[];
|
|
94
|
+
rowCount: number;
|
|
95
|
+
executionTime: number;
|
|
96
|
+
columns: string[];
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Metrics for monitoring
|
|
100
|
+
*/
|
|
101
|
+
interface DuckPondMetrics {
|
|
102
|
+
activeUsers: number;
|
|
103
|
+
totalQueries: number;
|
|
104
|
+
avgQueryTime: number;
|
|
105
|
+
cacheHitRate: number;
|
|
106
|
+
memoryUsage: number;
|
|
107
|
+
storageUsage: number;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Events emitted by DuckPond
|
|
111
|
+
*/
|
|
112
|
+
type DuckPondEvent = {
|
|
113
|
+
type: "user:attached";
|
|
114
|
+
userId: string;
|
|
115
|
+
timestamp: Date;
|
|
116
|
+
} | {
|
|
117
|
+
type: "user:detached";
|
|
118
|
+
userId: string;
|
|
119
|
+
reason: "eviction" | "manual";
|
|
120
|
+
timestamp: Date;
|
|
121
|
+
} | {
|
|
122
|
+
type: "query:executed";
|
|
123
|
+
userId: string;
|
|
124
|
+
duration: number;
|
|
125
|
+
timestamp: Date;
|
|
126
|
+
} | {
|
|
127
|
+
type: "query:failed";
|
|
128
|
+
userId: string;
|
|
129
|
+
error: string;
|
|
130
|
+
timestamp: Date;
|
|
131
|
+
} | {
|
|
132
|
+
type: "cache:hit";
|
|
133
|
+
userId: string;
|
|
134
|
+
} | {
|
|
135
|
+
type: "cache:miss";
|
|
136
|
+
userId: string;
|
|
137
|
+
} | {
|
|
138
|
+
type: "error";
|
|
139
|
+
error: Error;
|
|
140
|
+
timestamp: Date;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Type-safe result types using functype Either
|
|
144
|
+
*/
|
|
145
|
+
type DuckPondResult<T> = Either<DuckPondError, T>;
|
|
146
|
+
type AsyncDuckPondResult<T> = Promise<Either<DuckPondError, T>>;
|
|
147
|
+
/**
|
|
148
|
+
* Error types
|
|
149
|
+
*/
|
|
150
|
+
interface DuckPondError {
|
|
151
|
+
code: ErrorCode;
|
|
152
|
+
message: string;
|
|
153
|
+
cause?: Error;
|
|
154
|
+
context?: Record<string, unknown>;
|
|
155
|
+
}
|
|
156
|
+
declare enum ErrorCode {
|
|
157
|
+
CONNECTION_FAILED = "CONNECTION_FAILED",
|
|
158
|
+
CONNECTION_TIMEOUT = "CONNECTION_TIMEOUT",
|
|
159
|
+
R2_CONNECTION_ERROR = "R2_CONNECTION_ERROR",
|
|
160
|
+
S3_CONNECTION_ERROR = "S3_CONNECTION_ERROR",
|
|
161
|
+
USER_NOT_FOUND = "USER_NOT_FOUND",
|
|
162
|
+
USER_ALREADY_EXISTS = "USER_ALREADY_EXISTS",
|
|
163
|
+
USER_NOT_ATTACHED = "USER_NOT_ATTACHED",
|
|
164
|
+
QUERY_EXECUTION_ERROR = "QUERY_EXECUTION_ERROR",
|
|
165
|
+
QUERY_TIMEOUT = "QUERY_TIMEOUT",
|
|
166
|
+
INVALID_SQL = "INVALID_SQL",
|
|
167
|
+
MEMORY_LIMIT_EXCEEDED = "MEMORY_LIMIT_EXCEEDED",
|
|
168
|
+
STORAGE_ERROR = "STORAGE_ERROR",
|
|
169
|
+
STORAGE_QUOTA_EXCEEDED = "STORAGE_QUOTA_EXCEEDED",
|
|
170
|
+
INVALID_CONFIG = "INVALID_CONFIG",
|
|
171
|
+
NOT_INITIALIZED = "NOT_INITIALIZED",
|
|
172
|
+
UNKNOWN_ERROR = "UNKNOWN_ERROR"
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Configuration with defaults applied
|
|
176
|
+
*/
|
|
177
|
+
type ResolvedConfig = Required<Omit<DuckPondConfig, "r2" | "s3"> & {
|
|
178
|
+
r2: DuckPondConfig["r2"];
|
|
179
|
+
s3: DuckPondConfig["s3"];
|
|
180
|
+
}>;
|
|
181
|
+
|
|
182
|
+
export { type AsyncDuckPondResult, type ColumnSchema, type CreateUserOptions, type DuckPondConfig, type DuckPondError, type DuckPondEvent, type DuckPondMetrics, type DuckPondResult, ErrorCode, type FileInfo, type QueryResult, type ResolvedConfig, type Schema, type StorageStats, type TableSchema, type UserDatabase, type UserStats };
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/jordanburke/IdeaProjects/duckpond/dist/types.js"],"names":[],"mappings":"AAAA,+HAAkC,+BAA4B,uCAAuB","file":"/home/jordanburke/IdeaProjects/duckpond/dist/types.js"}
|
package/dist/types.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Either } from 'functype';
|
|
2
|
+
import { ErrorCode, DuckPondError } from '../types.mjs';
|
|
3
|
+
import '@duckdb/node-api';
|
|
4
|
+
import 'functype/either';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create a DuckPondError as a Left Either
|
|
8
|
+
*/
|
|
9
|
+
declare function createError(code: ErrorCode, message: string, cause?: Error, context?: Record<string, unknown>): Either<DuckPondError, never>;
|
|
10
|
+
/**
|
|
11
|
+
* Wrap a value in a Right Either
|
|
12
|
+
*/
|
|
13
|
+
declare function success<T = void>(value?: T): Either<DuckPondError, T extends void ? void : T>;
|
|
14
|
+
/**
|
|
15
|
+
* Convert an unknown error to a DuckPondError
|
|
16
|
+
*/
|
|
17
|
+
declare function toDuckPondError(error: unknown, defaultCode?: ErrorCode): DuckPondError;
|
|
18
|
+
/**
|
|
19
|
+
* Error factory functions for common errors
|
|
20
|
+
*/
|
|
21
|
+
declare const Errors: {
|
|
22
|
+
connectionFailed: (message: string, cause?: Error) => Either<DuckPondError, never>;
|
|
23
|
+
r2ConnectionError: (message: string, cause?: Error) => Either<DuckPondError, never>;
|
|
24
|
+
s3ConnectionError: (message: string, cause?: Error) => Either<DuckPondError, never>;
|
|
25
|
+
userNotFound: (userId: string) => Either<DuckPondError, never>;
|
|
26
|
+
userAlreadyExists: (userId: string) => Either<DuckPondError, never>;
|
|
27
|
+
userNotAttached: (userId: string) => Either<DuckPondError, never>;
|
|
28
|
+
queryExecutionError: (message: string, sql?: string, cause?: Error) => Either<DuckPondError, never>;
|
|
29
|
+
queryTimeout: (timeoutMs: number) => Either<DuckPondError, never>;
|
|
30
|
+
memoryLimitExceeded: (limit: string) => Either<DuckPondError, never>;
|
|
31
|
+
storageError: (message: string, cause?: Error) => Either<DuckPondError, never>;
|
|
32
|
+
invalidConfig: (message: string) => Either<DuckPondError, never>;
|
|
33
|
+
notInitialized: () => Either<DuckPondError, never>;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Format an error for logging
|
|
37
|
+
*/
|
|
38
|
+
declare function formatError(error: DuckPondError): string;
|
|
39
|
+
|
|
40
|
+
export { Errors, createError, formatError, success, toDuckPondError };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Either } from 'functype';
|
|
2
|
+
import { ErrorCode, DuckPondError } from '../types.js';
|
|
3
|
+
import '@duckdb/node-api';
|
|
4
|
+
import 'functype/either';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create a DuckPondError as a Left Either
|
|
8
|
+
*/
|
|
9
|
+
declare function createError(code: ErrorCode, message: string, cause?: Error, context?: Record<string, unknown>): Either<DuckPondError, never>;
|
|
10
|
+
/**
|
|
11
|
+
* Wrap a value in a Right Either
|
|
12
|
+
*/
|
|
13
|
+
declare function success<T = void>(value?: T): Either<DuckPondError, T extends void ? void : T>;
|
|
14
|
+
/**
|
|
15
|
+
* Convert an unknown error to a DuckPondError
|
|
16
|
+
*/
|
|
17
|
+
declare function toDuckPondError(error: unknown, defaultCode?: ErrorCode): DuckPondError;
|
|
18
|
+
/**
|
|
19
|
+
* Error factory functions for common errors
|
|
20
|
+
*/
|
|
21
|
+
declare const Errors: {
|
|
22
|
+
connectionFailed: (message: string, cause?: Error) => Either<DuckPondError, never>;
|
|
23
|
+
r2ConnectionError: (message: string, cause?: Error) => Either<DuckPondError, never>;
|
|
24
|
+
s3ConnectionError: (message: string, cause?: Error) => Either<DuckPondError, never>;
|
|
25
|
+
userNotFound: (userId: string) => Either<DuckPondError, never>;
|
|
26
|
+
userAlreadyExists: (userId: string) => Either<DuckPondError, never>;
|
|
27
|
+
userNotAttached: (userId: string) => Either<DuckPondError, never>;
|
|
28
|
+
queryExecutionError: (message: string, sql?: string, cause?: Error) => Either<DuckPondError, never>;
|
|
29
|
+
queryTimeout: (timeoutMs: number) => Either<DuckPondError, never>;
|
|
30
|
+
memoryLimitExceeded: (limit: string) => Either<DuckPondError, never>;
|
|
31
|
+
storageError: (message: string, cause?: Error) => Either<DuckPondError, never>;
|
|
32
|
+
invalidConfig: (message: string) => Either<DuckPondError, never>;
|
|
33
|
+
notInitialized: () => Either<DuckPondError, never>;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Format an error for logging
|
|
37
|
+
*/
|
|
38
|
+
declare function formatError(error: DuckPondError): string;
|
|
39
|
+
|
|
40
|
+
export { Errors, createError, formatError, success, toDuckPondError };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkMZTKR3LRjs = require('../chunk-MZTKR3LR.js');require('../chunk-E5ZZH3QB.js');require('../chunk-5XGN7UAV.js');exports.Errors = _chunkMZTKR3LRjs.d; exports.createError = _chunkMZTKR3LRjs.a; exports.formatError = _chunkMZTKR3LRjs.e; exports.success = _chunkMZTKR3LRjs.b; exports.toDuckPondError = _chunkMZTKR3LRjs.c;
|
|
2
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/jordanburke/IdeaProjects/duckpond/dist/utils/errors.js"],"names":[],"mappings":"AAAA,gIAA2C,gCAA6B,gCAA6B,4MAAwF","file":"/home/jordanburke/IdeaProjects/duckpond/dist/utils/errors.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create a namespaced logger for DuckPond
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* const log = createLogger('DuckPond')
|
|
8
|
+
* log('Initializing...')
|
|
9
|
+
*
|
|
10
|
+
* Enable with: DEBUG=duckpond:* node app.js
|
|
11
|
+
*/
|
|
12
|
+
declare function createLogger(namespace: string): debug.Debugger;
|
|
13
|
+
/**
|
|
14
|
+
* Pre-configured loggers for different modules
|
|
15
|
+
*/
|
|
16
|
+
declare const loggers: {
|
|
17
|
+
main: debug.Debugger;
|
|
18
|
+
cache: debug.Debugger;
|
|
19
|
+
connection: debug.Debugger;
|
|
20
|
+
query: debug.Debugger;
|
|
21
|
+
storage: debug.Debugger;
|
|
22
|
+
metrics: debug.Debugger;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export { createLogger, loggers };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create a namespaced logger for DuckPond
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* const log = createLogger('DuckPond')
|
|
8
|
+
* log('Initializing...')
|
|
9
|
+
*
|
|
10
|
+
* Enable with: DEBUG=duckpond:* node app.js
|
|
11
|
+
*/
|
|
12
|
+
declare function createLogger(namespace: string): debug.Debugger;
|
|
13
|
+
/**
|
|
14
|
+
* Pre-configured loggers for different modules
|
|
15
|
+
*/
|
|
16
|
+
declare const loggers: {
|
|
17
|
+
main: debug.Debugger;
|
|
18
|
+
cache: debug.Debugger;
|
|
19
|
+
connection: debug.Debugger;
|
|
20
|
+
query: debug.Debugger;
|
|
21
|
+
storage: debug.Debugger;
|
|
22
|
+
metrics: debug.Debugger;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export { createLogger, loggers };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/jordanburke/IdeaProjects/duckpond/dist/utils/logger.js"],"names":[],"mappings":"AAAA,gIAAqC,gCAA6B,gFAAuC","file":"/home/jordanburke/IdeaProjects/duckpond/dist/utils/logger.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "duckpond",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Multi-tenant DuckDB manager with R2/S3 storage and functional programming patterns",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"duckdb",
|
|
7
|
+
"r2",
|
|
8
|
+
"s3",
|
|
9
|
+
"cloudflare",
|
|
10
|
+
"multi-tenant",
|
|
11
|
+
"database",
|
|
12
|
+
"typescript",
|
|
13
|
+
"functype",
|
|
14
|
+
"functional-programming"
|
|
15
|
+
],
|
|
16
|
+
"author": "jordan.burke@gmail.com",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"homepage": "https://github.com/jordanburke/duckpond",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/jordanburke/duckpond"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
25
|
+
"@eslint/js": "^9.38.0",
|
|
26
|
+
"@types/node": "^22.18.11",
|
|
27
|
+
"@typescript-eslint/eslint-plugin": "^8.46.1",
|
|
28
|
+
"@typescript-eslint/parser": "^8.46.1",
|
|
29
|
+
"@vitest/coverage-v8": "3.2.4",
|
|
30
|
+
"@vitest/ui": "^3.2.4",
|
|
31
|
+
"cross-env": "^10.1.0",
|
|
32
|
+
"eslint": "^9.38.0",
|
|
33
|
+
"eslint-config-prettier": "^10.1.8",
|
|
34
|
+
"eslint-plugin-import": "^2.32.0",
|
|
35
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
36
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
37
|
+
"globals": "^16.4.0",
|
|
38
|
+
"prettier": "^3.6.2",
|
|
39
|
+
"rimraf": "^6.0.1",
|
|
40
|
+
"ts-node": "^10.9.2",
|
|
41
|
+
"tsup": "^8.5.0",
|
|
42
|
+
"typescript": "^5.9.3",
|
|
43
|
+
"vitest": "^3.2.4"
|
|
44
|
+
},
|
|
45
|
+
"main": "./dist/index.js",
|
|
46
|
+
"module": "./dist/index.mjs",
|
|
47
|
+
"types": "./dist/index.d.ts",
|
|
48
|
+
"exports": {
|
|
49
|
+
".": {
|
|
50
|
+
"types": "./dist/index.d.ts",
|
|
51
|
+
"require": "./dist/index.js",
|
|
52
|
+
"import": "./dist/index.mjs"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"files": [
|
|
56
|
+
"lib",
|
|
57
|
+
"dist"
|
|
58
|
+
],
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@duckdb/node-api": "1.4.1-r.4",
|
|
61
|
+
"@duckdb/node-bindings": "1.4.1-r.4",
|
|
62
|
+
"debug": "^4.4.3",
|
|
63
|
+
"functype": "^0.16.0"
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"validate": "pnpm format && pnpm lint && pnpm test && pnpm build",
|
|
67
|
+
"format": "prettier --write .",
|
|
68
|
+
"format:check": "prettier --check .",
|
|
69
|
+
"lint": "eslint ./src --fix",
|
|
70
|
+
"lint:check": "eslint ./src",
|
|
71
|
+
"test": "vitest run",
|
|
72
|
+
"test:watch": "vitest",
|
|
73
|
+
"test:coverage": "vitest run --coverage",
|
|
74
|
+
"test:ui": "vitest --ui",
|
|
75
|
+
"build": "rimraf dist && cross-env NODE_ENV=production tsup",
|
|
76
|
+
"build:watch": "tsup --watch",
|
|
77
|
+
"dev": "tsup --watch",
|
|
78
|
+
"ts-types": "tsc"
|
|
79
|
+
}
|
|
80
|
+
}
|