wn-turso 0.1.0 → 0.2.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/README.md +385 -0
- package/dist/adapters.d.ts +2 -0
- package/dist/adapters.js +5 -0
- package/dist/cli/index.d.ts +1 -6
- package/dist/cli/index.js +27 -34
- package/dist/config.d.ts +2 -77
- package/dist/config.js +25 -35
- package/dist/database.d.ts +2 -0
- package/dist/database.js +8 -0
- package/dist/embedded-adapter-aWF095Qo.js +92 -0
- package/dist/index.d.ts +2 -11
- package/dist/index.js +96 -15
- package/dist/pipeline-builder-ERaxT48h.js +275 -0
- package/dist/pipeline.d.ts +2 -0
- package/dist/pipeline.js +189 -0
- package/dist/{adapters → src/adapters}/adapter.d.ts +2 -5
- package/dist/src/adapters/adapter.d.ts.map +1 -0
- package/dist/{adapters → src/adapters}/embedded-adapter.d.ts +3 -6
- package/dist/src/adapters/embedded-adapter.d.ts.map +1 -0
- package/dist/src/adapters/index.d.ts.map +1 -0
- package/dist/{adapters → src/adapters}/remote-adapter.d.ts +3 -7
- package/dist/src/adapters/remote-adapter.d.ts.map +1 -0
- package/dist/src/cli/index.d.ts +6 -0
- package/dist/{cli → src/cli}/index.d.ts.map +1 -1
- package/dist/src/config.d.ts +74 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/database/index.d.ts.map +1 -0
- package/dist/{database → src/database}/kysely-query-service.d.ts +2 -5
- package/dist/src/database/kysely-query-service.d.ts.map +1 -0
- package/dist/{database → src/database}/turso-connection.d.ts +2 -5
- package/dist/src/database/turso-connection.d.ts.map +1 -0
- package/dist/{database → src/database}/turso-database.d.ts +3 -6
- package/dist/src/database/turso-database.d.ts.map +1 -0
- package/dist/{database → src/database}/turso-dialect.d.ts +3 -6
- package/dist/src/database/turso-dialect.d.ts.map +1 -0
- package/dist/{database → src/database}/turso-driver.d.ts +2 -5
- package/dist/src/database/turso-driver.d.ts.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/pipeline/index.d.ts.map +1 -0
- package/dist/{pipeline → src/pipeline}/operators.d.ts +3 -6
- package/dist/src/pipeline/operators.d.ts.map +1 -0
- package/dist/{pipeline → src/pipeline}/pipeline-builder.d.ts +12 -6
- package/dist/src/pipeline/pipeline-builder.d.ts.map +1 -0
- package/dist/src/pipeline/sink.d.ts +25 -0
- package/dist/src/pipeline/sink.d.ts.map +1 -0
- package/dist/src/pipeline/source.d.ts +23 -0
- package/dist/src/pipeline/source.d.ts.map +1 -0
- package/dist/src/pipeline/streams.d.ts +19 -0
- package/dist/src/pipeline/streams.d.ts.map +1 -0
- package/dist/{pipeline → src/pipeline}/types.d.ts +15 -7
- package/dist/src/pipeline/types.d.ts.map +1 -0
- package/dist/src/wordnet/index.d.ts.map +1 -0
- package/dist/{wordnet → src/wordnet}/turso-wordnet.d.ts +3 -7
- package/dist/src/wordnet/turso-wordnet.d.ts.map +1 -0
- package/dist/turso-database-CNWM_LV6.js +1669 -0
- package/package.json +14 -12
- package/dist/adapters/adapter.d.ts.map +0 -1
- package/dist/adapters/adapter.js +0 -4
- package/dist/adapters/embedded-adapter.d.ts.map +0 -1
- package/dist/adapters/embedded-adapter.js +0 -78
- package/dist/adapters/index.d.ts.map +0 -1
- package/dist/adapters/index.js +0 -5
- package/dist/adapters/remote-adapter.d.ts.map +0 -1
- package/dist/adapters/remote-adapter.js +0 -49
- package/dist/config.d.ts.map +0 -1
- package/dist/database/index.d.ts.map +0 -1
- package/dist/database/index.js +0 -8
- package/dist/database/kysely-query-service.d.ts.map +0 -1
- package/dist/database/kysely-query-service.js +0 -39
- package/dist/database/turso-connection.d.ts.map +0 -1
- package/dist/database/turso-connection.js +0 -29
- package/dist/database/turso-database.d.ts.map +0 -1
- package/dist/database/turso-database.js +0 -124
- package/dist/database/turso-dialect.d.ts.map +0 -1
- package/dist/database/turso-dialect.js +0 -25
- package/dist/database/turso-driver.d.ts.map +0 -1
- package/dist/database/turso-driver.js +0 -43
- package/dist/index.d.ts.map +0 -1
- package/dist/pipeline/index.d.ts.map +0 -1
- package/dist/pipeline/index.js +0 -13
- package/dist/pipeline/operators.d.ts.map +0 -1
- package/dist/pipeline/operators.js +0 -174
- package/dist/pipeline/pipeline-builder.d.ts.map +0 -1
- package/dist/pipeline/pipeline-builder.js +0 -181
- package/dist/pipeline/sink.d.ts +0 -22
- package/dist/pipeline/sink.d.ts.map +0 -1
- package/dist/pipeline/sink.js +0 -63
- package/dist/pipeline/source.d.ts +0 -20
- package/dist/pipeline/source.d.ts.map +0 -1
- package/dist/pipeline/source.js +0 -66
- package/dist/pipeline/streams.d.ts +0 -18
- package/dist/pipeline/streams.d.ts.map +0 -1
- package/dist/pipeline/streams.js +0 -115
- package/dist/pipeline/types.d.ts.map +0 -1
- package/dist/pipeline/types.js +0 -4
- package/dist/wordnet/index.d.ts.map +0 -1
- package/dist/wordnet/index.js +0 -4
- package/dist/wordnet/turso-wordnet.d.ts.map +0 -1
- package/dist/wordnet/turso-wordnet.js +0 -107
- /package/dist/{adapters → src/adapters}/index.d.ts +0 -0
- /package/dist/{database → src/database}/index.d.ts +0 -0
- /package/dist/{pipeline → src/pipeline}/index.d.ts +0 -0
- /package/dist/{wordnet → src/wordnet}/index.d.ts +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# wn-turso
|
|
2
|
+
|
|
3
|
+
Turso/libsql database backend and data pipeline utilities for WordNet.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Turso Database Integration** - Connect to Turso via HTTP (remote) or embedded replicas (local SQLite with sync)
|
|
8
|
+
- **Kysely Dialect** - Full Kysely support for type-safe SQL queries
|
|
9
|
+
- **Data Pipelines** - Functional, streaming data transfer between databases
|
|
10
|
+
- **Working DB Pattern** - Transform and extend data for runtime use cases
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add wn-turso
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Basic WordNet Queries
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { TursoWordnet } from "wn-turso";
|
|
24
|
+
|
|
25
|
+
// Remote mode (serverless)
|
|
26
|
+
const wn = new TursoWordnet({
|
|
27
|
+
url: "libsql://your-db.turso.io",
|
|
28
|
+
authToken: process.env.TURSO_AUTH_TOKEN,
|
|
29
|
+
mode: "remote",
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
await wn.initialize();
|
|
33
|
+
|
|
34
|
+
const synsets = await wn.synsets({ form: "computer", language: "en" });
|
|
35
|
+
const words = await wn.words({ form: "run", pos: "v" });
|
|
36
|
+
|
|
37
|
+
await wn.close();
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Embedded Replicas (Offline-capable)
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { TursoWordnet } from "wn-turso";
|
|
44
|
+
|
|
45
|
+
const wn = new TursoWordnet({
|
|
46
|
+
url: "file:./local-wordnet.db",
|
|
47
|
+
syncUrl: "libsql://your-db.turso.io",
|
|
48
|
+
authToken: process.env.TURSO_AUTH_TOKEN,
|
|
49
|
+
mode: "embedded",
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
await wn.initialize();
|
|
53
|
+
|
|
54
|
+
// Queries run against local SQLite
|
|
55
|
+
const synsets = await wn.synsets({ form: "computer" });
|
|
56
|
+
|
|
57
|
+
// Sync with remote when needed
|
|
58
|
+
await wn.sync();
|
|
59
|
+
|
|
60
|
+
await wn.close();
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Direct Database Access
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { TursoDatabase } from "wn-turso";
|
|
67
|
+
|
|
68
|
+
const db = new TursoDatabase({
|
|
69
|
+
url: "libsql://your-db.turso.io",
|
|
70
|
+
authToken: process.env.TURSO_AUTH_TOKEN,
|
|
71
|
+
mode: "remote",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
await db.initialize();
|
|
75
|
+
|
|
76
|
+
// Get Kysely instance for custom queries
|
|
77
|
+
const kysely = db.getDatabase();
|
|
78
|
+
const results = await kysely
|
|
79
|
+
.selectFrom("synsets")
|
|
80
|
+
.where("language", "=", "en")
|
|
81
|
+
.selectAll()
|
|
82
|
+
.execute();
|
|
83
|
+
|
|
84
|
+
// Get query service with all WordNet methods
|
|
85
|
+
const qs = db.getQueryService();
|
|
86
|
+
const lexicons = await qs.getLexicons();
|
|
87
|
+
|
|
88
|
+
await db.close();
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Pipeline System
|
|
92
|
+
|
|
93
|
+
The pipeline system enables streaming data transfers between databases with functional transformations.
|
|
94
|
+
|
|
95
|
+
### Basic Pipeline
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { Pipeline, tursoSource, tursoSink } from "wn-turso/pipeline";
|
|
99
|
+
|
|
100
|
+
const result = await Pipeline.from(tursoSource(sourceConfig, "synsets"))
|
|
101
|
+
.filter((row) => row.language === "en")
|
|
102
|
+
.map((row) => ({ ...row, processed: true }))
|
|
103
|
+
.to(tursoSink(destConfig, "synsets_backup"));
|
|
104
|
+
|
|
105
|
+
console.log(`Transferred ${result.inserted} rows in ${result.duration}ms`);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Working DB Pattern (Source of Truth → Runtime DB)
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { Pipeline, tursoSource, tursoSink } from "wn-turso/pipeline";
|
|
112
|
+
|
|
113
|
+
// Transfer from canonical DB to working DB with additional columns
|
|
114
|
+
const result = await Pipeline.from(tursoSource(sourceConfig, "synsets"))
|
|
115
|
+
.filter((row) => row.language === "en")
|
|
116
|
+
.extend((row) => ({
|
|
117
|
+
// Add runtime columns
|
|
118
|
+
cached_count: 0,
|
|
119
|
+
last_accessed: null,
|
|
120
|
+
popularity_score: computeScore(row),
|
|
121
|
+
source_db: "turso-main",
|
|
122
|
+
}))
|
|
123
|
+
.to(
|
|
124
|
+
tursoSink(workingConfig, "synsets_working", {
|
|
125
|
+
onConflict: "replace",
|
|
126
|
+
})
|
|
127
|
+
);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Checksum Deduplication (Skip Unchanged Rows)
|
|
131
|
+
|
|
132
|
+
Reduce write operations by skipping rows that haven't changed using checksum-based deduplication.
|
|
133
|
+
|
|
134
|
+
#### Operator-Level (Manual Control)
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import {
|
|
138
|
+
Pipeline,
|
|
139
|
+
tursoSource,
|
|
140
|
+
tursoSink,
|
|
141
|
+
loadChecksumsFromTable,
|
|
142
|
+
} from "wn-turso/pipeline";
|
|
143
|
+
|
|
144
|
+
// Load existing checksums from destination
|
|
145
|
+
const db = await getDestinationKysely();
|
|
146
|
+
const existingChecksums = await loadChecksumsFromTable(
|
|
147
|
+
db,
|
|
148
|
+
"synsets_working",
|
|
149
|
+
"id", // Key field
|
|
150
|
+
"_etl_checksum" // Checksum column
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// Pipeline will skip rows with matching checksums
|
|
154
|
+
const result = await Pipeline.from(tursoSource(sourceConfig, "synsets"))
|
|
155
|
+
.filter((row) => row.language === "en")
|
|
156
|
+
.deduplicateByChecksum({
|
|
157
|
+
keyField: "id",
|
|
158
|
+
checksumFields: ["definition", "pos", "ili"], // Hash these fields only
|
|
159
|
+
existingChecksums,
|
|
160
|
+
})
|
|
161
|
+
.to(tursoSink(destConfig, "synsets_working"));
|
|
162
|
+
|
|
163
|
+
console.log(`Skipped ${result.skipped_unchanged} unchanged rows`);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### Sink-Level (Automatic)
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { Pipeline, tursoSource, tursoSink } from "wn-turso/pipeline";
|
|
170
|
+
|
|
171
|
+
// Sink automatically compares checksums and skips unchanged rows
|
|
172
|
+
const result = await Pipeline.from(tursoSource(sourceConfig, "synsets"))
|
|
173
|
+
.filter((row) => row.language === "en")
|
|
174
|
+
.to(
|
|
175
|
+
tursoSink(destConfig, "synsets_working", {
|
|
176
|
+
checksumDeduplication: {
|
|
177
|
+
enabled: true,
|
|
178
|
+
keyField: "id",
|
|
179
|
+
fields: ["definition", "pos", "ili"], // Hash business fields only
|
|
180
|
+
checksumColumn: "_etl_checksum", // Column to store checksum
|
|
181
|
+
strategy: "skip", // 'skip' = don't write, 'update' = write anyway
|
|
182
|
+
},
|
|
183
|
+
})
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
console.log(
|
|
187
|
+
`Processed: ${result.processed}, Skipped: ${result.skipped_unchanged}`
|
|
188
|
+
);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Benefits:**
|
|
192
|
+
|
|
193
|
+
- **90%+ write reduction** on incremental syncs (typical)
|
|
194
|
+
- **Selective field hashing** - ignore metadata like timestamps
|
|
195
|
+
- **Production-proven pattern** - used by Airbyte, Fivetran, dbt
|
|
196
|
+
|
|
197
|
+
### Pipeline Operators
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { Pipeline, arraySource } from 'wn-turso/pipeline';
|
|
201
|
+
|
|
202
|
+
await Pipeline
|
|
203
|
+
.from(arraySource(data))
|
|
204
|
+
// Filtering
|
|
205
|
+
.filter(row => row.active)
|
|
206
|
+
|
|
207
|
+
// Transformation
|
|
208
|
+
.map(row => ({ ...row, upper: row.name.toUpperCase() }))
|
|
209
|
+
|
|
210
|
+
// Extend with new columns
|
|
211
|
+
.extend(row => ({ score: row.value * 2 }))
|
|
212
|
+
|
|
213
|
+
// Transform with null filtering
|
|
214
|
+
.transform(row => row.valid ? row : null)
|
|
215
|
+
|
|
216
|
+
// Side effects (logging, metrics)
|
|
217
|
+
.tap(row => console.log('Processing:', row.id))
|
|
218
|
+
|
|
219
|
+
// Pagination
|
|
220
|
+
.skip(10)
|
|
221
|
+
.take(100)
|
|
222
|
+
|
|
223
|
+
// Deduplication by key
|
|
224
|
+
.distinct(row => row.id)
|
|
225
|
+
|
|
226
|
+
// Checksum-based deduplication (skip unchanged)
|
|
227
|
+
.deduplicateByChecksum({ keyField: 'id', existingChecksums, checksumFields: [...] })
|
|
228
|
+
|
|
229
|
+
// Batching
|
|
230
|
+
.batch(50)
|
|
231
|
+
|
|
232
|
+
// Terminal operations
|
|
233
|
+
.toArray(); // Collect to array
|
|
234
|
+
.count(); // Count rows
|
|
235
|
+
.to(sink); // Write to sink
|
|
236
|
+
.forEach(fn); // Execute for each
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Low-Level Streaming
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import {
|
|
243
|
+
streamTable,
|
|
244
|
+
writeBatches,
|
|
245
|
+
tursoSource,
|
|
246
|
+
kyselySource,
|
|
247
|
+
} from "wn-turso/pipeline";
|
|
248
|
+
|
|
249
|
+
// Stream from any Kysely database
|
|
250
|
+
for await (const row of streamTable(kysely, "synsets", { batchSize: 1000 })) {
|
|
251
|
+
// Process row
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Write in batches
|
|
255
|
+
await writeBatches(kysely, "synsets", asyncIterable, {
|
|
256
|
+
batchSize: 100,
|
|
257
|
+
onConflict: "ignore",
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// Use with existing Kysely instance
|
|
261
|
+
const source = kyselySource(existingKysely, "words");
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Configuration
|
|
265
|
+
|
|
266
|
+
### TursoDatabaseConfig
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
interface TursoDatabaseConfig {
|
|
270
|
+
// Database URL
|
|
271
|
+
// Remote: 'libsql://your-db.turso.io'
|
|
272
|
+
// Embedded: 'file:./local.db'
|
|
273
|
+
url: string;
|
|
274
|
+
|
|
275
|
+
// Auth token (required for remote, optional for embedded without sync)
|
|
276
|
+
authToken?: string;
|
|
277
|
+
|
|
278
|
+
// Connection mode
|
|
279
|
+
mode: "remote" | "embedded";
|
|
280
|
+
|
|
281
|
+
// For embedded: remote URL to sync with
|
|
282
|
+
syncUrl?: string;
|
|
283
|
+
|
|
284
|
+
// Sync interval in ms (0 = manual only)
|
|
285
|
+
syncInterval?: number;
|
|
286
|
+
|
|
287
|
+
// Encryption key for embedded replicas
|
|
288
|
+
encryptionKey?: string;
|
|
289
|
+
|
|
290
|
+
// Read-only mode
|
|
291
|
+
readonly?: boolean;
|
|
292
|
+
|
|
293
|
+
// Enable foreign keys
|
|
294
|
+
enableForeignKeys?: boolean;
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## API Reference
|
|
299
|
+
|
|
300
|
+
### TursoWordnet
|
|
301
|
+
|
|
302
|
+
Main class for WordNet queries.
|
|
303
|
+
|
|
304
|
+
| Method | Description |
|
|
305
|
+
| ------------------- | --------------------- |
|
|
306
|
+
| `initialize()` | Connect to database |
|
|
307
|
+
| `synsets(options?)` | Query synsets |
|
|
308
|
+
| `words(options?)` | Query words |
|
|
309
|
+
| `senses(options?)` | Query senses |
|
|
310
|
+
| `lexicons()` | Get all lexicons |
|
|
311
|
+
| `sync()` | Sync embedded replica |
|
|
312
|
+
| `close()` | Close connection |
|
|
313
|
+
|
|
314
|
+
### TursoDatabase
|
|
315
|
+
|
|
316
|
+
Low-level database wrapper.
|
|
317
|
+
|
|
318
|
+
| Method | Description |
|
|
319
|
+
| ------------------- | ------------------------ |
|
|
320
|
+
| `initialize()` | Connect and setup schema |
|
|
321
|
+
| `getDatabase()` | Get Kysely instance |
|
|
322
|
+
| `getQueryService()` | Get query service |
|
|
323
|
+
| `getAdapter()` | Get underlying adapter |
|
|
324
|
+
| `sync()` | Sync embedded replica |
|
|
325
|
+
| `close()` | Close connection |
|
|
326
|
+
|
|
327
|
+
### Pipeline
|
|
328
|
+
|
|
329
|
+
Fluent pipeline builder.
|
|
330
|
+
|
|
331
|
+
| Method | Description |
|
|
332
|
+
| -------------------------------- | ------------------------------- |
|
|
333
|
+
| `from(source)` | Create pipeline from source |
|
|
334
|
+
| `filter(predicate)` | Filter rows |
|
|
335
|
+
| `map(fn)` | Transform rows |
|
|
336
|
+
| `extend(fn)` | Add properties to rows |
|
|
337
|
+
| `transform(fn)` | Transform with null filtering |
|
|
338
|
+
| `tap(fn)` | Side effect |
|
|
339
|
+
| `take(n)` | Take first n rows |
|
|
340
|
+
| `skip(n)` | Skip first n rows |
|
|
341
|
+
| `distinct(keyFn)` | Deduplicate by key |
|
|
342
|
+
| `deduplicateByChecksum(options)` | Skip unchanged rows by checksum |
|
|
343
|
+
| `batch(size)` | Batch into arrays |
|
|
344
|
+
| `to(sink)` | Write to sink |
|
|
345
|
+
| `toArray()` | Collect to array |
|
|
346
|
+
| `count()` | Count rows |
|
|
347
|
+
|
|
348
|
+
### Checksum Utilities
|
|
349
|
+
|
|
350
|
+
Functions for manual checksum management.
|
|
351
|
+
|
|
352
|
+
| Function | Description |
|
|
353
|
+
| --------------------------------------------------------------- | --------------------------------------- |
|
|
354
|
+
| `computeChecksum(data, fields?)` | Compute MD5 hash of row |
|
|
355
|
+
| `checksumBatch(rows, fields?)` | Compute checksums for array |
|
|
356
|
+
| `loadChecksumsFromTable(db, table, keyField, checksumColumn)` | Load existing checksums from DB |
|
|
357
|
+
| `compareChecksums(rows, keyField, existingChecksums, fields?)` | Compare rows against existing checksums |
|
|
358
|
+
| `filterChangedRows(rows, keyField, existingChecksums, fields?)` | Filter to only changed/new rows |
|
|
359
|
+
|
|
360
|
+
## CLI
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
# Upload local SQLite to Turso
|
|
364
|
+
wn-turso upload --url libsql://db.turso.io --token $TOKEN --input ./wordnet.db
|
|
365
|
+
|
|
366
|
+
# Sync embedded replica
|
|
367
|
+
wn-turso sync --url file:./local.db --token $TOKEN
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Testing
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
# Run all tests
|
|
374
|
+
pnpm test
|
|
375
|
+
|
|
376
|
+
# Run e2e tests only
|
|
377
|
+
pnpm test:e2e
|
|
378
|
+
|
|
379
|
+
# Watch mode
|
|
380
|
+
pnpm test:watch
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## License
|
|
384
|
+
|
|
385
|
+
MIT
|
package/dist/adapters.js
ADDED
package/dist/cli/index.d.ts
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -1,37 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
input: { type: 'string', short: 'i' },
|
|
14
|
-
output: { type: 'string', short: 'o' },
|
|
15
|
-
verbose: { type: 'boolean', short: 'v' },
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
const command = positionals[0];
|
|
19
|
-
switch (command) {
|
|
20
|
-
case 'upload':
|
|
21
|
-
console.log('Upload command - not yet implemented');
|
|
22
|
-
console.log('Will upload a local SQLite database to Turso');
|
|
23
|
-
break;
|
|
24
|
-
case 'sync':
|
|
25
|
-
console.log('Sync command - not yet implemented');
|
|
26
|
-
console.log('Will sync an embedded replica with Turso cloud');
|
|
27
|
-
break;
|
|
28
|
-
case 'help':
|
|
29
|
-
default:
|
|
30
|
-
showHelp();
|
|
2
|
+
import { parseArgs as e } from "util";
|
|
3
|
+
async function t() {
|
|
4
|
+
const { positionals: o } = e({
|
|
5
|
+
allowPositionals: !0,
|
|
6
|
+
options: {
|
|
7
|
+
help: { type: "boolean", short: "h" },
|
|
8
|
+
url: { type: "string" },
|
|
9
|
+
token: { type: "string", short: "t" },
|
|
10
|
+
input: { type: "string", short: "i" },
|
|
11
|
+
output: { type: "string", short: "o" },
|
|
12
|
+
verbose: { type: "boolean", short: "v" }
|
|
31
13
|
}
|
|
14
|
+
});
|
|
15
|
+
switch (o[0]) {
|
|
16
|
+
case "upload":
|
|
17
|
+
console.log("Upload command - not yet implemented"), console.log("Will upload a local SQLite database to Turso");
|
|
18
|
+
break;
|
|
19
|
+
case "sync":
|
|
20
|
+
console.log("Sync command - not yet implemented"), console.log("Will sync an embedded replica with Turso cloud");
|
|
21
|
+
break;
|
|
22
|
+
case "help":
|
|
23
|
+
default:
|
|
24
|
+
s();
|
|
25
|
+
}
|
|
32
26
|
}
|
|
33
|
-
function
|
|
34
|
-
|
|
27
|
+
function s() {
|
|
28
|
+
console.log(`
|
|
35
29
|
wn-turso - Turso database tools for WordNet
|
|
36
30
|
|
|
37
31
|
USAGE:
|
|
@@ -55,7 +49,6 @@ EXAMPLES:
|
|
|
55
49
|
wn-turso sync --url file:./local.db --token $TURSO_TOKEN
|
|
56
50
|
`);
|
|
57
51
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
process.exit(1);
|
|
52
|
+
t().catch((o) => {
|
|
53
|
+
console.error("Error:", o.message), process.exit(1);
|
|
61
54
|
});
|
package/dist/config.d.ts
CHANGED
|
@@ -1,77 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
import type { BaseDatabaseConfig } from 'wn-ts-core/shared';
|
|
5
|
-
/**
|
|
6
|
-
* Connection mode for Turso
|
|
7
|
-
* - 'remote': HTTP-only connection to Turso cloud
|
|
8
|
-
* - 'embedded': Local SQLite replica with Turso sync
|
|
9
|
-
*/
|
|
10
|
-
export type TursoConnectionMode = 'remote' | 'embedded';
|
|
11
|
-
/**
|
|
12
|
-
* Turso-specific database configuration
|
|
13
|
-
*/
|
|
14
|
-
export interface TursoDatabaseConfig extends BaseDatabaseConfig {
|
|
15
|
-
/**
|
|
16
|
-
* Turso database URL
|
|
17
|
-
* - For remote: libsql://db-org.turso.io
|
|
18
|
-
* - For embedded: file:./local.db
|
|
19
|
-
*/
|
|
20
|
-
url: string;
|
|
21
|
-
/**
|
|
22
|
-
* Auth token for Turso connection
|
|
23
|
-
* Required for remote connections and embedded sync
|
|
24
|
-
*/
|
|
25
|
-
authToken?: string;
|
|
26
|
-
/**
|
|
27
|
-
* Connection mode
|
|
28
|
-
* - 'remote': HTTP-only connection to Turso cloud
|
|
29
|
-
* - 'embedded': Local SQLite with Turso sync
|
|
30
|
-
*/
|
|
31
|
-
mode: TursoConnectionMode;
|
|
32
|
-
/**
|
|
33
|
-
* For embedded replicas: remote Turso URL to sync with
|
|
34
|
-
*/
|
|
35
|
-
syncUrl?: string;
|
|
36
|
-
/**
|
|
37
|
-
* Sync interval in milliseconds (for embedded mode)
|
|
38
|
-
* Default: 0 (manual sync only)
|
|
39
|
-
*/
|
|
40
|
-
syncInterval?: number;
|
|
41
|
-
/**
|
|
42
|
-
* Encryption key for embedded replicas
|
|
43
|
-
*/
|
|
44
|
-
encryptionKey?: string;
|
|
45
|
-
/**
|
|
46
|
-
* Connection timeout in milliseconds
|
|
47
|
-
*/
|
|
48
|
-
timeout?: number;
|
|
49
|
-
/**
|
|
50
|
-
* Enable foreign key constraints
|
|
51
|
-
*/
|
|
52
|
-
enableForeignKeys?: boolean;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Sync configuration for embedded replicas
|
|
56
|
-
*/
|
|
57
|
-
export interface SyncConfig {
|
|
58
|
-
/** Enable automatic sync */
|
|
59
|
-
autoSync: boolean;
|
|
60
|
-
/** Sync interval in ms */
|
|
61
|
-
interval: number;
|
|
62
|
-
/** Sync on startup */
|
|
63
|
-
syncOnStart: boolean;
|
|
64
|
-
/** Sync on close */
|
|
65
|
-
syncOnClose: boolean;
|
|
66
|
-
/** Maximum retry attempts */
|
|
67
|
-
maxRetries: number;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Default sync configuration
|
|
71
|
-
*/
|
|
72
|
-
export declare const defaultSyncConfig: SyncConfig;
|
|
73
|
-
/**
|
|
74
|
-
* Validate Turso configuration
|
|
75
|
-
*/
|
|
76
|
-
export declare function validateTursoConfig(config: TursoDatabaseConfig): void;
|
|
77
|
-
//# sourceMappingURL=config.d.ts.map
|
|
1
|
+
export * from './src/config'
|
|
2
|
+
export {}
|
package/dist/config.js
CHANGED
|
@@ -1,37 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export const defaultSyncConfig = {
|
|
8
|
-
autoSync: false,
|
|
9
|
-
interval: 0,
|
|
10
|
-
syncOnStart: true,
|
|
11
|
-
syncOnClose: true,
|
|
12
|
-
maxRetries: 3,
|
|
1
|
+
const t = {
|
|
2
|
+
autoSync: !1,
|
|
3
|
+
interval: 0,
|
|
4
|
+
syncOnStart: !0,
|
|
5
|
+
syncOnClose: !0,
|
|
6
|
+
maxRetries: 3
|
|
13
7
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (!
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (config.mode === 'embedded') {
|
|
30
|
-
if (!config.url.startsWith('file:')) {
|
|
31
|
-
throw new Error('Turso config: embedded URL must start with file:');
|
|
32
|
-
}
|
|
33
|
-
if (config.syncUrl && !config.authToken) {
|
|
34
|
-
throw new Error('Turso config: authToken is required when syncUrl is provided');
|
|
35
|
-
}
|
|
36
|
-
}
|
|
8
|
+
function e(r) {
|
|
9
|
+
if (!r.url)
|
|
10
|
+
throw new Error("Turso config: url is required");
|
|
11
|
+
if (r.mode === "remote") {
|
|
12
|
+
if (!r.authToken)
|
|
13
|
+
throw new Error("Turso config: authToken is required for remote mode");
|
|
14
|
+
if (!r.url.startsWith("libsql://") && !r.url.startsWith("https://"))
|
|
15
|
+
throw new Error("Turso config: remote URL must start with libsql:// or https://");
|
|
16
|
+
}
|
|
17
|
+
if (r.mode === "embedded") {
|
|
18
|
+
if (!r.url.startsWith("file:"))
|
|
19
|
+
throw new Error("Turso config: embedded URL must start with file:");
|
|
20
|
+
if (r.syncUrl && !r.authToken)
|
|
21
|
+
throw new Error("Turso config: authToken is required when syncUrl is provided");
|
|
22
|
+
}
|
|
37
23
|
}
|
|
24
|
+
export {
|
|
25
|
+
t as defaultSyncConfig,
|
|
26
|
+
e as validateTursoConfig
|
|
27
|
+
};
|