@furlow/pipes 0.2.1 → 1.0.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/dist/database/index.d.ts +71 -2
- package/dist/database/index.js +274 -2
- package/dist/database/index.js.map +1 -1
- package/dist/file/index.d.ts +65 -2
- package/dist/file/index.js +183 -2
- package/dist/file/index.js.map +1 -1
- package/dist/http/index.d.ts +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +465 -0
- package/dist/index.js.map +1 -1
- package/dist/mqtt/index.d.ts +1 -1
- package/dist/tcp/index.d.ts +1 -1
- package/dist/{types-BW9r2ksN.d.ts → types-B6Zdv6jc.d.ts} +50 -1
- package/dist/webhook/index.d.ts +1 -1
- package/dist/websocket/index.d.ts +1 -1
- package/package.json +3 -2
package/dist/database/index.d.ts
CHANGED
|
@@ -1,3 +1,72 @@
|
|
|
1
|
-
|
|
1
|
+
import { a as DatabaseEvent, P as Pipe, c as DatabasePipeConfig, k as PipeResponse, b as DatabaseEventType } from '../types-B6Zdv6jc.js';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Database pipe for reactive database operations
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
interface DatabasePipeOptions {
|
|
8
|
+
name: string;
|
|
9
|
+
config: DatabasePipeConfig;
|
|
10
|
+
}
|
|
11
|
+
type DatabaseEventHandler = (event: DatabaseEvent) => void | Promise<void>;
|
|
12
|
+
declare class DatabasePipe implements Pipe {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly type = "database";
|
|
15
|
+
private config;
|
|
16
|
+
private connected;
|
|
17
|
+
private db;
|
|
18
|
+
private eventHandlers;
|
|
19
|
+
constructor(options: DatabasePipeOptions);
|
|
20
|
+
/**
|
|
21
|
+
* Connect to the database
|
|
22
|
+
*/
|
|
23
|
+
connect(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Disconnect from the database
|
|
26
|
+
*/
|
|
27
|
+
disconnect(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Check if connected
|
|
30
|
+
*/
|
|
31
|
+
isConnected(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Execute a raw SQL query
|
|
34
|
+
*/
|
|
35
|
+
query<T = Record<string, unknown>[]>(sql: string, params?: unknown[]): Promise<PipeResponse<T>>;
|
|
36
|
+
/**
|
|
37
|
+
* Insert a row into a table
|
|
38
|
+
*/
|
|
39
|
+
insert(table: string, data: Record<string, unknown>): Promise<PipeResponse<{
|
|
40
|
+
lastInsertRowid?: number | bigint;
|
|
41
|
+
}>>;
|
|
42
|
+
/**
|
|
43
|
+
* Update rows in a table
|
|
44
|
+
*/
|
|
45
|
+
update(table: string, where: Record<string, unknown>, data: Record<string, unknown>): Promise<PipeResponse<{
|
|
46
|
+
changes?: number;
|
|
47
|
+
}>>;
|
|
48
|
+
/**
|
|
49
|
+
* Delete rows from a table
|
|
50
|
+
*/
|
|
51
|
+
delete(table: string, where: Record<string, unknown>): Promise<PipeResponse<{
|
|
52
|
+
changes?: number;
|
|
53
|
+
}>>;
|
|
54
|
+
/**
|
|
55
|
+
* Register an event handler
|
|
56
|
+
*/
|
|
57
|
+
on(event: DatabaseEventType | 'change' | 'connected' | 'disconnected', handler: DatabaseEventHandler): void;
|
|
58
|
+
/**
|
|
59
|
+
* Remove an event handler
|
|
60
|
+
*/
|
|
61
|
+
off(event: DatabaseEventType | 'change' | 'connected' | 'disconnected', handler: DatabaseEventHandler): void;
|
|
62
|
+
/**
|
|
63
|
+
* Emit an event
|
|
64
|
+
*/
|
|
65
|
+
private emit;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create a database pipe
|
|
69
|
+
*/
|
|
70
|
+
declare function createDatabasePipe(options: DatabasePipeOptions): DatabasePipe;
|
|
71
|
+
|
|
72
|
+
export { type DatabaseEventHandler, DatabasePipe, type DatabasePipeOptions, createDatabasePipe };
|
package/dist/database/index.js
CHANGED
|
@@ -1,8 +1,280 @@
|
|
|
1
1
|
// src/database/index.ts
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var DatabasePipe = class {
|
|
3
|
+
name;
|
|
4
|
+
type = "database";
|
|
5
|
+
config;
|
|
6
|
+
connected = false;
|
|
7
|
+
db = null;
|
|
8
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this.name = options.name;
|
|
11
|
+
this.config = options.config;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Connect to the database
|
|
15
|
+
*/
|
|
16
|
+
async connect() {
|
|
17
|
+
if (this.connected) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
if (this.config.adapter === "sqlite") {
|
|
22
|
+
const BetterSqlite3 = (await import("better-sqlite3")).default;
|
|
23
|
+
const connectionString = typeof this.config.connection === "string" ? this.config.connection : ":memory:";
|
|
24
|
+
this.db = new BetterSqlite3(connectionString);
|
|
25
|
+
} else if (this.config.adapter === "memory") {
|
|
26
|
+
this.db = new MemoryDatabase();
|
|
27
|
+
} else {
|
|
28
|
+
throw new Error(`Unsupported adapter: ${this.config.adapter}`);
|
|
29
|
+
}
|
|
30
|
+
this.connected = true;
|
|
31
|
+
this.emit("connected", {
|
|
32
|
+
type: "insert",
|
|
33
|
+
table: "",
|
|
34
|
+
data: {}
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
38
|
+
throw new Error(`Failed to connect to database: ${message}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Disconnect from the database
|
|
43
|
+
*/
|
|
44
|
+
async disconnect() {
|
|
45
|
+
if (!this.connected) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
if (this.config.adapter === "sqlite" && this.db) {
|
|
50
|
+
this.db.close();
|
|
51
|
+
}
|
|
52
|
+
this.db = null;
|
|
53
|
+
this.connected = false;
|
|
54
|
+
this.emit("disconnected", {
|
|
55
|
+
type: "delete",
|
|
56
|
+
table: "",
|
|
57
|
+
data: {}
|
|
58
|
+
});
|
|
59
|
+
} catch {
|
|
60
|
+
this.db = null;
|
|
61
|
+
this.connected = false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check if connected
|
|
66
|
+
*/
|
|
67
|
+
isConnected() {
|
|
68
|
+
return this.connected;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Execute a raw SQL query
|
|
72
|
+
*/
|
|
73
|
+
async query(sql, params = []) {
|
|
74
|
+
if (!this.isConnected()) {
|
|
75
|
+
return { success: false, error: "Not connected" };
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
if (this.config.adapter === "sqlite") {
|
|
79
|
+
const stmt = this.db.prepare(sql);
|
|
80
|
+
if (sql.trim().toUpperCase().startsWith("SELECT")) {
|
|
81
|
+
const rows = stmt.all(...params);
|
|
82
|
+
return { success: true, data: rows };
|
|
83
|
+
} else {
|
|
84
|
+
const result = stmt.run(...params);
|
|
85
|
+
return { success: true, data: result };
|
|
86
|
+
}
|
|
87
|
+
} else if (this.config.adapter === "memory") {
|
|
88
|
+
const result = this.db.query(sql, params);
|
|
89
|
+
return { success: true, data: result };
|
|
90
|
+
}
|
|
91
|
+
return { success: false, error: "Unsupported adapter" };
|
|
92
|
+
} catch (error) {
|
|
93
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
94
|
+
return { success: false, error: message };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Insert a row into a table
|
|
99
|
+
*/
|
|
100
|
+
async insert(table, data) {
|
|
101
|
+
if (!this.isConnected()) {
|
|
102
|
+
return { success: false, error: "Not connected" };
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
const columns = Object.keys(data);
|
|
106
|
+
const values = Object.values(data);
|
|
107
|
+
const placeholders = columns.map(() => "?").join(", ");
|
|
108
|
+
const sql = `INSERT INTO ${table} (${columns.join(", ")}) VALUES (${placeholders})`;
|
|
109
|
+
let result = {};
|
|
110
|
+
if (this.config.adapter === "sqlite") {
|
|
111
|
+
const stmt = this.db.prepare(sql);
|
|
112
|
+
result = stmt.run(...values);
|
|
113
|
+
} else if (this.config.adapter === "memory") {
|
|
114
|
+
result = this.db.insert(table, data);
|
|
115
|
+
}
|
|
116
|
+
const event = {
|
|
117
|
+
type: "insert",
|
|
118
|
+
table,
|
|
119
|
+
data
|
|
120
|
+
};
|
|
121
|
+
this.emit("insert", event);
|
|
122
|
+
this.emit("change", event);
|
|
123
|
+
return { success: true, data: result };
|
|
124
|
+
} catch (error) {
|
|
125
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
126
|
+
return { success: false, error: message };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Update rows in a table
|
|
131
|
+
*/
|
|
132
|
+
async update(table, where, data) {
|
|
133
|
+
if (!this.isConnected()) {
|
|
134
|
+
return { success: false, error: "Not connected" };
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const setClauses = Object.keys(data).map((key) => `${key} = ?`).join(", ");
|
|
138
|
+
const whereClauses = Object.keys(where).map((key) => `${key} = ?`).join(" AND ");
|
|
139
|
+
const sql = `UPDATE ${table} SET ${setClauses} WHERE ${whereClauses}`;
|
|
140
|
+
const params = [...Object.values(data), ...Object.values(where)];
|
|
141
|
+
let result = {};
|
|
142
|
+
if (this.config.adapter === "sqlite") {
|
|
143
|
+
const stmt = this.db.prepare(sql);
|
|
144
|
+
result = stmt.run(...params);
|
|
145
|
+
} else if (this.config.adapter === "memory") {
|
|
146
|
+
result = this.db.update(table, where, data);
|
|
147
|
+
}
|
|
148
|
+
const event = {
|
|
149
|
+
type: "update",
|
|
150
|
+
table,
|
|
151
|
+
data,
|
|
152
|
+
oldData: where
|
|
153
|
+
};
|
|
154
|
+
this.emit("update", event);
|
|
155
|
+
this.emit("change", event);
|
|
156
|
+
return { success: true, data: result };
|
|
157
|
+
} catch (error) {
|
|
158
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
159
|
+
return { success: false, error: message };
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Delete rows from a table
|
|
164
|
+
*/
|
|
165
|
+
async delete(table, where) {
|
|
166
|
+
if (!this.isConnected()) {
|
|
167
|
+
return { success: false, error: "Not connected" };
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const whereClauses = Object.keys(where).map((key) => `${key} = ?`).join(" AND ");
|
|
171
|
+
const sql = `DELETE FROM ${table} WHERE ${whereClauses}`;
|
|
172
|
+
const params = Object.values(where);
|
|
173
|
+
let result = {};
|
|
174
|
+
if (this.config.adapter === "sqlite") {
|
|
175
|
+
const stmt = this.db.prepare(sql);
|
|
176
|
+
result = stmt.run(...params);
|
|
177
|
+
} else if (this.config.adapter === "memory") {
|
|
178
|
+
result = this.db.delete(table, where);
|
|
179
|
+
}
|
|
180
|
+
const event = {
|
|
181
|
+
type: "delete",
|
|
182
|
+
table,
|
|
183
|
+
data: where
|
|
184
|
+
};
|
|
185
|
+
this.emit("delete", event);
|
|
186
|
+
this.emit("change", event);
|
|
187
|
+
return { success: true, data: result };
|
|
188
|
+
} catch (error) {
|
|
189
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
190
|
+
return { success: false, error: message };
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Register an event handler
|
|
195
|
+
*/
|
|
196
|
+
on(event, handler) {
|
|
197
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
198
|
+
handlers.push(handler);
|
|
199
|
+
this.eventHandlers.set(event, handlers);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Remove an event handler
|
|
203
|
+
*/
|
|
204
|
+
off(event, handler) {
|
|
205
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
206
|
+
const index = handlers.indexOf(handler);
|
|
207
|
+
if (index !== -1) {
|
|
208
|
+
handlers.splice(index, 1);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Emit an event
|
|
213
|
+
*/
|
|
214
|
+
emit(event, data) {
|
|
215
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
216
|
+
for (const handler of handlers) {
|
|
217
|
+
try {
|
|
218
|
+
handler(data);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error(`Database handler error for "${event}":`, error);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
4
224
|
};
|
|
225
|
+
var MemoryDatabase = class {
|
|
226
|
+
tables = /* @__PURE__ */ new Map();
|
|
227
|
+
autoIncrements = /* @__PURE__ */ new Map();
|
|
228
|
+
query(sql, _params) {
|
|
229
|
+
const selectMatch = sql.match(/SELECT \* FROM (\w+)/i);
|
|
230
|
+
if (selectMatch) {
|
|
231
|
+
const table = selectMatch[1];
|
|
232
|
+
return this.tables.get(table) ?? [];
|
|
233
|
+
}
|
|
234
|
+
return [];
|
|
235
|
+
}
|
|
236
|
+
insert(table, data) {
|
|
237
|
+
if (!this.tables.has(table)) {
|
|
238
|
+
this.tables.set(table, []);
|
|
239
|
+
}
|
|
240
|
+
const id = (this.autoIncrements.get(table) ?? 0) + 1;
|
|
241
|
+
this.autoIncrements.set(table, id);
|
|
242
|
+
const row = { id, ...data };
|
|
243
|
+
this.tables.get(table).push(row);
|
|
244
|
+
return { lastInsertRowid: id };
|
|
245
|
+
}
|
|
246
|
+
update(table, where, data) {
|
|
247
|
+
const rows = this.tables.get(table) ?? [];
|
|
248
|
+
let changes = 0;
|
|
249
|
+
for (const row of rows) {
|
|
250
|
+
if (this.matchesWhere(row, where)) {
|
|
251
|
+
Object.assign(row, data);
|
|
252
|
+
changes++;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return { changes };
|
|
256
|
+
}
|
|
257
|
+
delete(table, where) {
|
|
258
|
+
const rows = this.tables.get(table) ?? [];
|
|
259
|
+
const initialLength = rows.length;
|
|
260
|
+
const remaining = rows.filter((row) => !this.matchesWhere(row, where));
|
|
261
|
+
this.tables.set(table, remaining);
|
|
262
|
+
return { changes: initialLength - remaining.length };
|
|
263
|
+
}
|
|
264
|
+
matchesWhere(row, where) {
|
|
265
|
+
for (const [key, value] of Object.entries(where)) {
|
|
266
|
+
if (row[key] !== value) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
function createDatabasePipe(options) {
|
|
274
|
+
return new DatabasePipe(options);
|
|
275
|
+
}
|
|
5
276
|
export {
|
|
277
|
+
DatabasePipe,
|
|
6
278
|
createDatabasePipe
|
|
7
279
|
};
|
|
8
280
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/database/index.ts"],"sourcesContent":["// External database pipe - placeholder\nexport const createDatabasePipe = () => { throw new Error('Not implemented'); };\n"],"mappings":";AACO,IAAM,qBAAqB,MAAM;AAAE,QAAM,IAAI,MAAM,iBAAiB;AAAG;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/database/index.ts"],"sourcesContent":["/**\n * Database pipe for reactive database operations\n */\n\nimport type {\n Pipe,\n PipeResponse,\n DatabasePipeConfig,\n DatabaseEvent,\n DatabaseEventType,\n} from '../types.js';\n\nexport interface DatabasePipeOptions {\n name: string;\n config: DatabasePipeConfig;\n}\n\nexport type DatabaseEventHandler = (event: DatabaseEvent) => void | Promise<void>;\n\nexport class DatabasePipe implements Pipe {\n public readonly name: string;\n public readonly type = 'database';\n private config: DatabasePipeConfig;\n private connected = false;\n private db: any = null;\n private eventHandlers: Map<string, DatabaseEventHandler[]> = new Map();\n\n constructor(options: DatabasePipeOptions) {\n this.name = options.name;\n this.config = options.config;\n }\n\n /**\n * Connect to the database\n */\n async connect(): Promise<void> {\n if (this.connected) {\n return;\n }\n\n try {\n if (this.config.adapter === 'sqlite') {\n // Dynamic import to avoid bundling issues\n const BetterSqlite3 = (await import('better-sqlite3')).default;\n const connectionString =\n typeof this.config.connection === 'string'\n ? this.config.connection\n : ':memory:';\n this.db = new BetterSqlite3(connectionString);\n } else if (this.config.adapter === 'memory') {\n // In-memory storage using a simple object\n this.db = new MemoryDatabase();\n } else {\n throw new Error(`Unsupported adapter: ${this.config.adapter}`);\n }\n\n this.connected = true;\n this.emit('connected', {\n type: 'insert',\n table: '',\n data: {},\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to connect to database: ${message}`);\n }\n }\n\n /**\n * Disconnect from the database\n */\n async disconnect(): Promise<void> {\n if (!this.connected) {\n return;\n }\n\n try {\n if (this.config.adapter === 'sqlite' && this.db) {\n this.db.close();\n }\n this.db = null;\n this.connected = false;\n this.emit('disconnected', {\n type: 'delete',\n table: '',\n data: {},\n });\n } catch {\n // Ignore close errors\n this.db = null;\n this.connected = false;\n }\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Execute a raw SQL query\n */\n async query<T = Record<string, unknown>[]>(\n sql: string,\n params: unknown[] = []\n ): Promise<PipeResponse<T>> {\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n try {\n if (this.config.adapter === 'sqlite') {\n const stmt = this.db.prepare(sql);\n // Check if it's a SELECT query\n if (sql.trim().toUpperCase().startsWith('SELECT')) {\n const rows = stmt.all(...params);\n return { success: true, data: rows as T };\n } else {\n const result = stmt.run(...params);\n return { success: true, data: result as T };\n }\n } else if (this.config.adapter === 'memory') {\n const result = this.db.query(sql, params);\n return { success: true, data: result as T };\n }\n\n return { success: false, error: 'Unsupported adapter' };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { success: false, error: message };\n }\n }\n\n /**\n * Insert a row into a table\n */\n async insert(\n table: string,\n data: Record<string, unknown>\n ): Promise<PipeResponse<{ lastInsertRowid?: number | bigint }>> {\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n try {\n const columns = Object.keys(data);\n const values = Object.values(data);\n const placeholders = columns.map(() => '?').join(', ');\n const sql = `INSERT INTO ${table} (${columns.join(', ')}) VALUES (${placeholders})`;\n\n let result: { lastInsertRowid?: number | bigint } = {};\n\n if (this.config.adapter === 'sqlite') {\n const stmt = this.db.prepare(sql);\n result = stmt.run(...values);\n } else if (this.config.adapter === 'memory') {\n result = this.db.insert(table, data);\n }\n\n // Emit insert event\n const event: DatabaseEvent = {\n type: 'insert',\n table,\n data,\n };\n this.emit('insert', event);\n this.emit('change', event);\n\n return { success: true, data: result };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { success: false, error: message };\n }\n }\n\n /**\n * Update rows in a table\n */\n async update(\n table: string,\n where: Record<string, unknown>,\n data: Record<string, unknown>\n ): Promise<PipeResponse<{ changes?: number }>> {\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n try {\n const setClauses = Object.keys(data)\n .map((key) => `${key} = ?`)\n .join(', ');\n const whereClauses = Object.keys(where)\n .map((key) => `${key} = ?`)\n .join(' AND ');\n const sql = `UPDATE ${table} SET ${setClauses} WHERE ${whereClauses}`;\n const params = [...Object.values(data), ...Object.values(where)];\n\n let result: { changes?: number } = {};\n\n if (this.config.adapter === 'sqlite') {\n const stmt = this.db.prepare(sql);\n result = stmt.run(...params);\n } else if (this.config.adapter === 'memory') {\n result = this.db.update(table, where, data);\n }\n\n // Emit update event\n const event: DatabaseEvent = {\n type: 'update',\n table,\n data,\n oldData: where,\n };\n this.emit('update', event);\n this.emit('change', event);\n\n return { success: true, data: result };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { success: false, error: message };\n }\n }\n\n /**\n * Delete rows from a table\n */\n async delete(\n table: string,\n where: Record<string, unknown>\n ): Promise<PipeResponse<{ changes?: number }>> {\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n try {\n const whereClauses = Object.keys(where)\n .map((key) => `${key} = ?`)\n .join(' AND ');\n const sql = `DELETE FROM ${table} WHERE ${whereClauses}`;\n const params = Object.values(where);\n\n let result: { changes?: number } = {};\n\n if (this.config.adapter === 'sqlite') {\n const stmt = this.db.prepare(sql);\n result = stmt.run(...params);\n } else if (this.config.adapter === 'memory') {\n result = this.db.delete(table, where);\n }\n\n // Emit delete event\n const event: DatabaseEvent = {\n type: 'delete',\n table,\n data: where,\n };\n this.emit('delete', event);\n this.emit('change', event);\n\n return { success: true, data: result };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { success: false, error: message };\n }\n }\n\n /**\n * Register an event handler\n */\n on(event: DatabaseEventType | 'change' | 'connected' | 'disconnected', handler: DatabaseEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n handlers.push(handler);\n this.eventHandlers.set(event, handlers);\n }\n\n /**\n * Remove an event handler\n */\n off(event: DatabaseEventType | 'change' | 'connected' | 'disconnected', handler: DatabaseEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n const index = handlers.indexOf(handler);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit an event\n */\n private emit(event: string, data: DatabaseEvent): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n console.error(`Database handler error for \"${event}\":`, error);\n }\n }\n }\n}\n\n/**\n * Simple in-memory database for testing\n */\nclass MemoryDatabase {\n private tables: Map<string, Record<string, unknown>[]> = new Map();\n private autoIncrements: Map<string, number> = new Map();\n\n query(sql: string, _params: unknown[]): Record<string, unknown>[] {\n // Very basic SQL parsing for memory adapter\n const selectMatch = sql.match(/SELECT \\* FROM (\\w+)/i);\n if (selectMatch) {\n const table = selectMatch[1]!;\n return this.tables.get(table) ?? [];\n }\n return [];\n }\n\n insert(table: string, data: Record<string, unknown>): { lastInsertRowid: number } {\n if (!this.tables.has(table)) {\n this.tables.set(table, []);\n }\n\n const id = (this.autoIncrements.get(table) ?? 0) + 1;\n this.autoIncrements.set(table, id);\n\n const row = { id, ...data };\n this.tables.get(table)!.push(row);\n\n return { lastInsertRowid: id };\n }\n\n update(\n table: string,\n where: Record<string, unknown>,\n data: Record<string, unknown>\n ): { changes: number } {\n const rows = this.tables.get(table) ?? [];\n let changes = 0;\n\n for (const row of rows) {\n if (this.matchesWhere(row, where)) {\n Object.assign(row, data);\n changes++;\n }\n }\n\n return { changes };\n }\n\n delete(table: string, where: Record<string, unknown>): { changes: number } {\n const rows = this.tables.get(table) ?? [];\n const initialLength = rows.length;\n\n const remaining = rows.filter((row) => !this.matchesWhere(row, where));\n this.tables.set(table, remaining);\n\n return { changes: initialLength - remaining.length };\n }\n\n private matchesWhere(\n row: Record<string, unknown>,\n where: Record<string, unknown>\n ): boolean {\n for (const [key, value] of Object.entries(where)) {\n if (row[key] !== value) {\n return false;\n }\n }\n return true;\n }\n}\n\n/**\n * Create a database pipe\n */\nexport function createDatabasePipe(options: DatabasePipeOptions): DatabasePipe {\n return new DatabasePipe(options);\n}\n"],"mappings":"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","names":[]}
|
package/dist/file/index.d.ts
CHANGED
|
@@ -1,3 +1,66 @@
|
|
|
1
|
-
|
|
1
|
+
import { F as FileEvent, P as Pipe, e as FilePipeConfig, d as FileEventType } from '../types-B6Zdv6jc.js';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* File pipe for file system watching
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
interface FilePipeOptions {
|
|
8
|
+
name: string;
|
|
9
|
+
config: FilePipeConfig;
|
|
10
|
+
}
|
|
11
|
+
type FileEventHandler = (event: FileEvent) => void | Promise<void>;
|
|
12
|
+
declare class FilePipe implements Pipe {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly type = "file";
|
|
15
|
+
private watcher;
|
|
16
|
+
private config;
|
|
17
|
+
private watching;
|
|
18
|
+
private eventHandlers;
|
|
19
|
+
constructor(options: FilePipeOptions);
|
|
20
|
+
/**
|
|
21
|
+
* Start watching files (alias for connect)
|
|
22
|
+
*/
|
|
23
|
+
watch(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Start watching files
|
|
26
|
+
*/
|
|
27
|
+
connect(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Stop watching files
|
|
30
|
+
*/
|
|
31
|
+
disconnect(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Check if watching
|
|
34
|
+
*/
|
|
35
|
+
isConnected(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Add paths to watch
|
|
38
|
+
*/
|
|
39
|
+
add(paths: string | string[]): void;
|
|
40
|
+
/**
|
|
41
|
+
* Stop watching specific paths
|
|
42
|
+
*/
|
|
43
|
+
unwatch(paths: string | string[]): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get watched paths
|
|
46
|
+
*/
|
|
47
|
+
getWatched(): Record<string, string[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Register an event handler
|
|
50
|
+
*/
|
|
51
|
+
on(event: FileEventType | 'all' | 'error', handler: FileEventHandler): void;
|
|
52
|
+
/**
|
|
53
|
+
* Remove an event handler
|
|
54
|
+
*/
|
|
55
|
+
off(event: FileEventType | 'all' | 'error', handler: FileEventHandler): void;
|
|
56
|
+
/**
|
|
57
|
+
* Emit an event
|
|
58
|
+
*/
|
|
59
|
+
private emit;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Create a file pipe
|
|
63
|
+
*/
|
|
64
|
+
declare function createFilePipe(options: FilePipeOptions): FilePipe;
|
|
65
|
+
|
|
66
|
+
export { type FileEventHandler, FilePipe, type FilePipeOptions, createFilePipe };
|
package/dist/file/index.js
CHANGED
|
@@ -1,8 +1,189 @@
|
|
|
1
1
|
// src/file/index.ts
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import chokidar from "chokidar";
|
|
3
|
+
var FilePipe = class {
|
|
4
|
+
name;
|
|
5
|
+
type = "file";
|
|
6
|
+
watcher = null;
|
|
7
|
+
config;
|
|
8
|
+
watching = false;
|
|
9
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.name = options.name;
|
|
12
|
+
this.config = options.config;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Start watching files (alias for connect)
|
|
16
|
+
*/
|
|
17
|
+
async watch() {
|
|
18
|
+
return this.connect();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Start watching files
|
|
22
|
+
*/
|
|
23
|
+
async connect() {
|
|
24
|
+
if (this.watching) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
try {
|
|
29
|
+
this.watcher = chokidar.watch(this.config.paths, {
|
|
30
|
+
ignored: this.config.ignore,
|
|
31
|
+
persistent: this.config.persistent ?? true,
|
|
32
|
+
usePolling: this.config.usePolling ?? false,
|
|
33
|
+
ignoreInitial: true
|
|
34
|
+
});
|
|
35
|
+
this.watcher.on("ready", () => {
|
|
36
|
+
this.watching = true;
|
|
37
|
+
resolve();
|
|
38
|
+
});
|
|
39
|
+
this.watcher.on("error", (error) => {
|
|
40
|
+
if (!this.watching) {
|
|
41
|
+
reject(error);
|
|
42
|
+
}
|
|
43
|
+
this.emit("error", {
|
|
44
|
+
type: "change",
|
|
45
|
+
path: ""
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
this.watcher.on("add", (path, stats) => {
|
|
49
|
+
const event = {
|
|
50
|
+
type: "add",
|
|
51
|
+
path,
|
|
52
|
+
stats: stats ? {
|
|
53
|
+
size: stats.size,
|
|
54
|
+
mtime: stats.mtime,
|
|
55
|
+
isDirectory: stats.isDirectory()
|
|
56
|
+
} : void 0
|
|
57
|
+
};
|
|
58
|
+
this.emit("add", event);
|
|
59
|
+
this.emit("all", event);
|
|
60
|
+
});
|
|
61
|
+
this.watcher.on("change", (path, stats) => {
|
|
62
|
+
const event = {
|
|
63
|
+
type: "change",
|
|
64
|
+
path,
|
|
65
|
+
stats: stats ? {
|
|
66
|
+
size: stats.size,
|
|
67
|
+
mtime: stats.mtime,
|
|
68
|
+
isDirectory: stats.isDirectory()
|
|
69
|
+
} : void 0
|
|
70
|
+
};
|
|
71
|
+
this.emit("change", event);
|
|
72
|
+
this.emit("all", event);
|
|
73
|
+
});
|
|
74
|
+
this.watcher.on("unlink", (path) => {
|
|
75
|
+
const event = {
|
|
76
|
+
type: "unlink",
|
|
77
|
+
path
|
|
78
|
+
};
|
|
79
|
+
this.emit("unlink", event);
|
|
80
|
+
this.emit("all", event);
|
|
81
|
+
});
|
|
82
|
+
this.watcher.on("addDir", (path, stats) => {
|
|
83
|
+
const event = {
|
|
84
|
+
type: "addDir",
|
|
85
|
+
path,
|
|
86
|
+
stats: stats ? {
|
|
87
|
+
size: stats.size,
|
|
88
|
+
mtime: stats.mtime,
|
|
89
|
+
isDirectory: true
|
|
90
|
+
} : void 0
|
|
91
|
+
};
|
|
92
|
+
this.emit("addDir", event);
|
|
93
|
+
this.emit("all", event);
|
|
94
|
+
});
|
|
95
|
+
this.watcher.on("unlinkDir", (path) => {
|
|
96
|
+
const event = {
|
|
97
|
+
type: "unlinkDir",
|
|
98
|
+
path
|
|
99
|
+
};
|
|
100
|
+
this.emit("unlinkDir", event);
|
|
101
|
+
this.emit("all", event);
|
|
102
|
+
});
|
|
103
|
+
} catch (error) {
|
|
104
|
+
reject(error);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Stop watching files
|
|
110
|
+
*/
|
|
111
|
+
async disconnect() {
|
|
112
|
+
if (!this.watcher) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
await this.watcher.close();
|
|
116
|
+
this.watcher = null;
|
|
117
|
+
this.watching = false;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Check if watching
|
|
121
|
+
*/
|
|
122
|
+
isConnected() {
|
|
123
|
+
return this.watching;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Add paths to watch
|
|
127
|
+
*/
|
|
128
|
+
add(paths) {
|
|
129
|
+
if (this.watcher) {
|
|
130
|
+
this.watcher.add(paths);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Stop watching specific paths
|
|
135
|
+
*/
|
|
136
|
+
unwatch(paths) {
|
|
137
|
+
if (this.watcher) {
|
|
138
|
+
this.watcher.unwatch(paths);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get watched paths
|
|
143
|
+
*/
|
|
144
|
+
getWatched() {
|
|
145
|
+
if (this.watcher) {
|
|
146
|
+
return this.watcher.getWatched();
|
|
147
|
+
}
|
|
148
|
+
return {};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Register an event handler
|
|
152
|
+
*/
|
|
153
|
+
on(event, handler) {
|
|
154
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
155
|
+
handlers.push(handler);
|
|
156
|
+
this.eventHandlers.set(event, handlers);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Remove an event handler
|
|
160
|
+
*/
|
|
161
|
+
off(event, handler) {
|
|
162
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
163
|
+
const index = handlers.indexOf(handler);
|
|
164
|
+
if (index !== -1) {
|
|
165
|
+
handlers.splice(index, 1);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Emit an event
|
|
170
|
+
*/
|
|
171
|
+
emit(event, data) {
|
|
172
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
173
|
+
for (const handler of handlers) {
|
|
174
|
+
try {
|
|
175
|
+
handler(data);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error(`File handler error for "${event}":`, error);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
4
181
|
};
|
|
182
|
+
function createFilePipe(options) {
|
|
183
|
+
return new FilePipe(options);
|
|
184
|
+
}
|
|
5
185
|
export {
|
|
186
|
+
FilePipe,
|
|
6
187
|
createFilePipe
|
|
7
188
|
};
|
|
8
189
|
//# sourceMappingURL=index.js.map
|
package/dist/file/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/file/index.ts"],"sourcesContent":["// File watcher
|
|
1
|
+
{"version":3,"sources":["../../src/file/index.ts"],"sourcesContent":["/**\n * File pipe for file system watching\n */\n\nimport chokidar, { FSWatcher } from 'chokidar';\nimport type { Pipe, PipeResponse, FilePipeConfig, FileEvent, FileEventType } from '../types.js';\n\nexport interface FilePipeOptions {\n name: string;\n config: FilePipeConfig;\n}\n\nexport type FileEventHandler = (event: FileEvent) => void | Promise<void>;\n\nexport class FilePipe implements Pipe {\n public readonly name: string;\n public readonly type = 'file';\n private watcher: FSWatcher | null = null;\n private config: FilePipeConfig;\n private watching = false;\n private eventHandlers: Map<string, FileEventHandler[]> = new Map();\n\n constructor(options: FilePipeOptions) {\n this.name = options.name;\n this.config = options.config;\n }\n\n /**\n * Start watching files (alias for connect)\n */\n async watch(): Promise<void> {\n return this.connect();\n }\n\n /**\n * Start watching files\n */\n async connect(): Promise<void> {\n if (this.watching) {\n return;\n }\n\n return new Promise((resolve, reject) => {\n try {\n this.watcher = chokidar.watch(this.config.paths, {\n ignored: this.config.ignore,\n persistent: this.config.persistent ?? true,\n usePolling: this.config.usePolling ?? false,\n ignoreInitial: true,\n });\n\n this.watcher.on('ready', () => {\n this.watching = true;\n resolve();\n });\n\n this.watcher.on('error', (error) => {\n if (!this.watching) {\n reject(error);\n }\n this.emit('error', {\n type: 'change',\n path: '',\n });\n });\n\n // File events\n this.watcher.on('add', (path, stats) => {\n const event: FileEvent = {\n type: 'add',\n path,\n stats: stats\n ? {\n size: stats.size,\n mtime: stats.mtime,\n isDirectory: stats.isDirectory(),\n }\n : undefined,\n };\n this.emit('add', event);\n this.emit('all', event);\n });\n\n this.watcher.on('change', (path, stats) => {\n const event: FileEvent = {\n type: 'change',\n path,\n stats: stats\n ? {\n size: stats.size,\n mtime: stats.mtime,\n isDirectory: stats.isDirectory(),\n }\n : undefined,\n };\n this.emit('change', event);\n this.emit('all', event);\n });\n\n this.watcher.on('unlink', (path) => {\n const event: FileEvent = {\n type: 'unlink',\n path,\n };\n this.emit('unlink', event);\n this.emit('all', event);\n });\n\n // Directory events\n this.watcher.on('addDir', (path, stats) => {\n const event: FileEvent = {\n type: 'addDir',\n path,\n stats: stats\n ? {\n size: stats.size,\n mtime: stats.mtime,\n isDirectory: true,\n }\n : undefined,\n };\n this.emit('addDir', event);\n this.emit('all', event);\n });\n\n this.watcher.on('unlinkDir', (path) => {\n const event: FileEvent = {\n type: 'unlinkDir',\n path,\n };\n this.emit('unlinkDir', event);\n this.emit('all', event);\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Stop watching files\n */\n async disconnect(): Promise<void> {\n if (!this.watcher) {\n return;\n }\n\n await this.watcher.close();\n this.watcher = null;\n this.watching = false;\n }\n\n /**\n * Check if watching\n */\n isConnected(): boolean {\n return this.watching;\n }\n\n /**\n * Add paths to watch\n */\n add(paths: string | string[]): void {\n if (this.watcher) {\n this.watcher.add(paths);\n }\n }\n\n /**\n * Stop watching specific paths\n */\n unwatch(paths: string | string[]): void {\n if (this.watcher) {\n this.watcher.unwatch(paths);\n }\n }\n\n /**\n * Get watched paths\n */\n getWatched(): Record<string, string[]> {\n if (this.watcher) {\n return this.watcher.getWatched();\n }\n return {};\n }\n\n /**\n * Register an event handler\n */\n on(event: FileEventType | 'all' | 'error', handler: FileEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n handlers.push(handler);\n this.eventHandlers.set(event, handlers);\n }\n\n /**\n * Remove an event handler\n */\n off(event: FileEventType | 'all' | 'error', handler: FileEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n const index = handlers.indexOf(handler);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit an event\n */\n private emit(event: string, data: FileEvent): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n console.error(`File handler error for \"${event}\":`, error);\n }\n }\n }\n}\n\n/**\n * Create a file pipe\n */\nexport function createFilePipe(options: FilePipeOptions): FilePipe {\n return new FilePipe(options);\n}\n"],"mappings":"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","names":[]}
|
package/dist/http/index.d.ts
CHANGED