@malloydata/db-duckdb 0.0.390 → 0.0.392
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/duckdb_common.js +11 -3
- package/dist/duckdb_config.d.ts +2 -0
- package/dist/duckdb_config.js +8 -3
- package/dist/duckdb_connection.d.ts +32 -0
- package/dist/duckdb_connection.js +124 -10
- package/dist/native.js +10 -0
- package/package.json +3 -2
package/dist/duckdb_common.js
CHANGED
|
@@ -32,6 +32,14 @@ const unquoteName = (name) => {
|
|
|
32
32
|
}
|
|
33
33
|
return name;
|
|
34
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* A bare or schema-qualified SQL identifier — `name` or `schema.name`. Anything
|
|
37
|
+
* else (file paths with dashes, dots-as-extensions, slashes, URL schemes,
|
|
38
|
+
* globs) is treated as a file-path string by `fetchTableSchema` and wrapped
|
|
39
|
+
* in single quotes so DuckDB sees it as a string literal rather than parsing
|
|
40
|
+
* it as a SQL identifier.
|
|
41
|
+
*/
|
|
42
|
+
const SQL_IDENTIFIER_CHAIN = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
|
|
35
43
|
class DuckDBCommon extends connection_1.BaseConnection {
|
|
36
44
|
get dialectName() {
|
|
37
45
|
return this.dialect.name;
|
|
@@ -123,9 +131,9 @@ class DuckDBCommon extends connection_1.BaseConnection {
|
|
|
123
131
|
connection: this.name,
|
|
124
132
|
fields: [],
|
|
125
133
|
};
|
|
126
|
-
const quotedTablePath =
|
|
127
|
-
?
|
|
128
|
-
: tablePath
|
|
134
|
+
const quotedTablePath = SQL_IDENTIFIER_CHAIN.test(tablePath)
|
|
135
|
+
? tablePath
|
|
136
|
+
: `'${tablePath}'`;
|
|
129
137
|
const infoQuery = `DESCRIBE SELECT * FROM ${quotedTablePath}`;
|
|
130
138
|
await this.schemaFromQuery(infoQuery, structDef);
|
|
131
139
|
return structDef;
|
package/dist/duckdb_config.d.ts
CHANGED
|
@@ -34,6 +34,8 @@ export interface NormalizedDuckDBConfig {
|
|
|
34
34
|
motherDuckToken?: string;
|
|
35
35
|
additionalExtensions: string[];
|
|
36
36
|
setupSQL?: string;
|
|
37
|
+
shareable: boolean;
|
|
38
|
+
effectiveShareable: boolean;
|
|
37
39
|
}
|
|
38
40
|
export declare class DuckDBConfigValidationError extends Error {
|
|
39
41
|
constructor(message: string);
|
package/dist/duckdb_config.js
CHANGED
|
@@ -60,7 +60,7 @@ const REQUIRED_BASELINE_EXTENSIONS = ['icu', 'json'];
|
|
|
60
60
|
const DERIVED_TEMP_DIRECTORY_NAME = '.tmp';
|
|
61
61
|
const DERIVED_SECRET_DIRECTORY_NAME = '.duckdb-secrets';
|
|
62
62
|
function normalizeDuckDBConfig(config) {
|
|
63
|
-
var _a, _b, _c, _d;
|
|
63
|
+
var _a, _b, _c, _d, _e;
|
|
64
64
|
const securityPolicy = parseSecurityPolicy(config['securityPolicy']);
|
|
65
65
|
if (securityPolicy === 'sandboxed' && !pathSecurity.isPosixHost()) {
|
|
66
66
|
throw new DuckDBConfigValidationError('securityPolicy "sandboxed" is only supported on POSIX hosts');
|
|
@@ -70,6 +70,7 @@ function normalizeDuckDBConfig(config) {
|
|
|
70
70
|
const rawSetupSQL = normalizeOptionalText(readOptionalString(config, 'setupSQL'));
|
|
71
71
|
const rawMotherDuckToken = normalizeOptionalText(readOptionalString(config, 'motherDuckToken'));
|
|
72
72
|
const readOnly = (_c = readOptionalBoolean(config, 'readOnly')) !== null && _c !== void 0 ? _c : false;
|
|
73
|
+
const shareable = (_d = readOptionalBoolean(config, 'shareable')) !== null && _d !== void 0 ? _d : false;
|
|
73
74
|
const additionalExtensions = normalizeExtensions(config['additionalExtensions'], 'additionalExtensions');
|
|
74
75
|
const enableExternalAccess = readOptionalBoolean(config, 'enableExternalAccess');
|
|
75
76
|
const lockConfiguration = readOptionalBoolean(config, 'lockConfiguration');
|
|
@@ -175,7 +176,7 @@ function normalizeDuckDBConfig(config) {
|
|
|
175
176
|
? undefined
|
|
176
177
|
: canonicalizeConfigPath(rawExtensionDirectory, 'extensionDirectory');
|
|
177
178
|
const secretDirectory = deriveRestrictedSecretDirectory({
|
|
178
|
-
requiresSecretNeutralization: (
|
|
179
|
+
requiresSecretNeutralization: (_e = safetyPolicy === null || safetyPolicy === void 0 ? void 0 : safetyPolicy.requiresSecretNeutralization) !== null && _e !== void 0 ? _e : false,
|
|
179
180
|
tempDirectory,
|
|
180
181
|
workingDirectory,
|
|
181
182
|
});
|
|
@@ -206,6 +207,10 @@ function normalizeDuckDBConfig(config) {
|
|
|
206
207
|
motherDuckToken: rawMotherDuckToken,
|
|
207
208
|
additionalExtensions,
|
|
208
209
|
setupSQL: rawSetupSQL,
|
|
210
|
+
shareable,
|
|
211
|
+
effectiveShareable: shareable &&
|
|
212
|
+
databasePath !== ':memory:' &&
|
|
213
|
+
!isLikelyRemoteDatabasePath(databasePath),
|
|
209
214
|
};
|
|
210
215
|
}
|
|
211
216
|
function buildDuckDBShareKey(config) {
|
|
@@ -226,7 +231,7 @@ function buildDuckDBShareKey(config) {
|
|
|
226
231
|
? ''
|
|
227
232
|
: String(config.allowUnsignedExtensions), config.tempFileEncryption === undefined
|
|
228
233
|
? ''
|
|
229
|
-
: String(config.tempFileEncryption), config.threads === undefined ? '' : String(config.threads), (_c = config.memoryLimit) !== null && _c !== void 0 ? _c : '', (_d = config.tempDirectory) !== null && _d !== void 0 ? _d : '', (_e = config.workingDirectory) !== null && _e !== void 0 ? _e : '', ...[...config.additionalExtensions].sort(), (_f = config.extensionDirectory) !== null && _f !== void 0 ? _f : '', (_g = config.motherDuckToken) !== null && _g !== void 0 ? _g : '');
|
|
234
|
+
: String(config.tempFileEncryption), config.threads === undefined ? '' : String(config.threads), (_c = config.memoryLimit) !== null && _c !== void 0 ? _c : '', (_d = config.tempDirectory) !== null && _d !== void 0 ? _d : '', (_e = config.workingDirectory) !== null && _e !== void 0 ? _e : '', ...[...config.additionalExtensions].sort(), (_f = config.extensionDirectory) !== null && _f !== void 0 ? _f : '', (_g = config.motherDuckToken) !== null && _g !== void 0 ? _g : '', String(config.effectiveShareable));
|
|
230
235
|
}
|
|
231
236
|
function sqlStringLiteral(value) {
|
|
232
237
|
return `'${value.replace(/'/g, "''")}'`;
|
|
@@ -22,6 +22,7 @@ export interface DuckDBConnectionOptions extends ConnectionConfig {
|
|
|
22
22
|
memoryLimit?: string;
|
|
23
23
|
tempDirectory?: string;
|
|
24
24
|
extensionDirectory?: string;
|
|
25
|
+
shareable?: boolean;
|
|
25
26
|
}
|
|
26
27
|
interface ActiveDB {
|
|
27
28
|
instance: DuckDBInstance;
|
|
@@ -44,6 +45,28 @@ export declare class DuckDBConnection extends DuckDBCommon {
|
|
|
44
45
|
* from reversible idle.
|
|
45
46
|
*/
|
|
46
47
|
protected closed: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Shareable mode only. The DuckDBInstance backing this connection's
|
|
50
|
+
* `:memory:` primary database. Not shared via `activeDBs` because each
|
|
51
|
+
* shareable connection independently ATTACHes/DETACHes the real file —
|
|
52
|
+
* there is nothing to pool. Closed in `close()`.
|
|
53
|
+
*/
|
|
54
|
+
private ownedInstance;
|
|
55
|
+
/**
|
|
56
|
+
* Shareable mode only. True between a successful ATTACH (in
|
|
57
|
+
* `setupOnce()`) and the matching DETACH (in `idle()` / `close()`).
|
|
58
|
+
*/
|
|
59
|
+
private attached;
|
|
60
|
+
/**
|
|
61
|
+
* Shareable mode only. True after the first successful run of the
|
|
62
|
+
* once-per-connection portion of `setupOnce()` (baseline `SET`s,
|
|
63
|
+
* extension `LOAD`s, user `setupSQL`, `lockConfiguration`). Those run
|
|
64
|
+
* against the persistent `:memory:` primary and must NOT re-run on
|
|
65
|
+
* later wake-ups: user `setupSQL` may be non-idempotent, and any later
|
|
66
|
+
* `SET` would fail under `lockConfiguration=true`. Wake-ups still
|
|
67
|
+
* re-ATTACH the real file because that's the bit DETACH released.
|
|
68
|
+
*/
|
|
69
|
+
private connectionSetupRan;
|
|
47
70
|
static activeDBs: Record<string, ActiveDB>;
|
|
48
71
|
constructor(options: DuckDBConnectionOptions, queryOptions?: QueryOptionsReader);
|
|
49
72
|
constructor(name: string, databasePath?: string, workingDirectory?: string, queryOptions?: QueryOptionsReader);
|
|
@@ -51,6 +74,14 @@ export declare class DuckDBConnection extends DuckDBCommon {
|
|
|
51
74
|
private init;
|
|
52
75
|
protected setup(): Promise<void>;
|
|
53
76
|
private setupOnce;
|
|
77
|
+
/**
|
|
78
|
+
* Shareable mode: ATTACH the real database file into the in-memory
|
|
79
|
+
* primary and `USE` it, so unqualified table refs resolve into the
|
|
80
|
+
* attached file. Idempotent — guarded by `this.attached`. Runs after
|
|
81
|
+
* `applyFinalBaseline()` so the corresponding `SET allowed_directories`
|
|
82
|
+
* (sandboxed mode) has already been applied.
|
|
83
|
+
*/
|
|
84
|
+
private attachIfShareable;
|
|
54
85
|
private buildInstanceOptions;
|
|
55
86
|
private shouldApplyEnableExternalAccessAtOpenTime;
|
|
56
87
|
private applyFinalBaseline;
|
|
@@ -63,6 +94,7 @@ export declare class DuckDBConnection extends DuckDBCommon {
|
|
|
63
94
|
runSQLStream(sql: string, { rowLimit, abortSignal }?: RunSQLOptions): AsyncIterableIterator<QueryRecord>;
|
|
64
95
|
close(): Promise<void>;
|
|
65
96
|
idle(): Promise<void>;
|
|
97
|
+
private detachShareableFile;
|
|
66
98
|
/**
|
|
67
99
|
* Drop our entry from the shared `activeDBs` bookkeeping. If we were
|
|
68
100
|
* the last sharer, close the underlying `DuckDBInstance`.
|
|
@@ -31,6 +31,7 @@ const node_api_1 = require("@duckdb/node-api");
|
|
|
31
31
|
const malloy_1 = require("@malloydata/malloy");
|
|
32
32
|
const package_json_1 = __importDefault(require("@malloydata/malloy/package.json"));
|
|
33
33
|
const duckdb_config_1 = require("./duckdb_config");
|
|
34
|
+
const SHAREABLE_ATTACH_ALIAS = 'malloy_db';
|
|
34
35
|
class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
|
|
35
36
|
constructor(arg, arg2, workingDirectory, queryOptions) {
|
|
36
37
|
var _a;
|
|
@@ -42,6 +43,28 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
42
43
|
* from reversible idle.
|
|
43
44
|
*/
|
|
44
45
|
this.closed = false;
|
|
46
|
+
/**
|
|
47
|
+
* Shareable mode only. The DuckDBInstance backing this connection's
|
|
48
|
+
* `:memory:` primary database. Not shared via `activeDBs` because each
|
|
49
|
+
* shareable connection independently ATTACHes/DETACHes the real file —
|
|
50
|
+
* there is nothing to pool. Closed in `close()`.
|
|
51
|
+
*/
|
|
52
|
+
this.ownedInstance = null;
|
|
53
|
+
/**
|
|
54
|
+
* Shareable mode only. True between a successful ATTACH (in
|
|
55
|
+
* `setupOnce()`) and the matching DETACH (in `idle()` / `close()`).
|
|
56
|
+
*/
|
|
57
|
+
this.attached = false;
|
|
58
|
+
/**
|
|
59
|
+
* Shareable mode only. True after the first successful run of the
|
|
60
|
+
* once-per-connection portion of `setupOnce()` (baseline `SET`s,
|
|
61
|
+
* extension `LOAD`s, user `setupSQL`, `lockConfiguration`). Those run
|
|
62
|
+
* against the persistent `:memory:` primary and must NOT re-run on
|
|
63
|
+
* later wake-ups: user `setupSQL` may be non-idempotent, and any later
|
|
64
|
+
* `SET` would fail under `lockConfiguration=true`. Wake-ups still
|
|
65
|
+
* re-ATTACH the real file because that's the bit DETACH released.
|
|
66
|
+
*/
|
|
67
|
+
this.connectionSetupRan = false;
|
|
45
68
|
const options = typeof arg === 'string'
|
|
46
69
|
? buildLegacyOptions(arg, arg2, workingDirectory)
|
|
47
70
|
: arg;
|
|
@@ -72,6 +95,15 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
72
95
|
}
|
|
73
96
|
async init() {
|
|
74
97
|
try {
|
|
98
|
+
if (this.normalized.effectiveShareable) {
|
|
99
|
+
// Shareable mode: own private :memory: primary, no activeDBs
|
|
100
|
+
// sharing. The real database file is opened lazily via ATTACH in
|
|
101
|
+
// setupOnce() and released via DETACH in idle().
|
|
102
|
+
const instance = await node_api_1.DuckDBInstance.create(':memory:', this.buildInstanceOptions({ forShareablePrimary: true }));
|
|
103
|
+
this.connection = await instance.connect();
|
|
104
|
+
this.ownedInstance = instance;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
75
107
|
const cached = DuckDBConnection.activeDBs[this.shareKey];
|
|
76
108
|
if (cached) {
|
|
77
109
|
this.connection = await cached.instance.connect();
|
|
@@ -116,24 +148,65 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
116
148
|
await this.isSetup;
|
|
117
149
|
}
|
|
118
150
|
async setupOnce() {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
151
|
+
// In non-shareable mode this whole method runs on every wake because
|
|
152
|
+
// the underlying DuckDBInstance was destroyed by `idle()`/`close()`,
|
|
153
|
+
// so the connection-level state (SETs, LOADs, user setupSQL effects)
|
|
154
|
+
// is gone and must be replayed.
|
|
155
|
+
//
|
|
156
|
+
// In shareable mode the `:memory:` primary survives idle and so does
|
|
157
|
+
// its connection-level state. Replaying the baseline + user setupSQL
|
|
158
|
+
// on a second wake would re-execute non-idempotent user statements
|
|
159
|
+
// (CREATE TABLE, INSERT, ...) and would also fail outright under
|
|
160
|
+
// `lockConfiguration=true` because subsequent `SET`s are rejected
|
|
161
|
+
// once configuration is locked. Gate everything except the ATTACH on
|
|
162
|
+
// `connectionSetupRan` so it only runs the first time.
|
|
163
|
+
const reattachOnly = this.normalized.effectiveShareable && this.connectionSetupRan;
|
|
164
|
+
if (!reattachOnly) {
|
|
165
|
+
await this.applyFinalBaseline();
|
|
166
|
+
}
|
|
167
|
+
await this.attachIfShareable();
|
|
168
|
+
if (!reattachOnly) {
|
|
169
|
+
if (this.normalized.setupSQL) {
|
|
170
|
+
for (const statement of splitSetupSQL(this.normalized.setupSQL)) {
|
|
171
|
+
await this.runDuckDBQuery(statement);
|
|
172
|
+
}
|
|
123
173
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
174
|
+
if (this.normalized.lockConfiguration) {
|
|
175
|
+
await this.runDuckDBQuery('SET lock_configuration=true');
|
|
176
|
+
}
|
|
177
|
+
this.connectionSetupRan = true;
|
|
127
178
|
}
|
|
128
179
|
}
|
|
129
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Shareable mode: ATTACH the real database file into the in-memory
|
|
182
|
+
* primary and `USE` it, so unqualified table refs resolve into the
|
|
183
|
+
* attached file. Idempotent — guarded by `this.attached`. Runs after
|
|
184
|
+
* `applyFinalBaseline()` so the corresponding `SET allowed_directories`
|
|
185
|
+
* (sandboxed mode) has already been applied.
|
|
186
|
+
*/
|
|
187
|
+
async attachIfShareable() {
|
|
188
|
+
if (!this.normalized.effectiveShareable)
|
|
189
|
+
return;
|
|
190
|
+
if (this.attached)
|
|
191
|
+
return;
|
|
192
|
+
const readOnlyClause = this.normalized.readOnly ? ' (READ_ONLY)' : '';
|
|
193
|
+
await this.runDuckDBQuery(`ATTACH ${(0, duckdb_config_1.sqlStringLiteral)(this.normalized.databasePath)} AS ${SHAREABLE_ATTACH_ALIAS}${readOnlyClause}`);
|
|
194
|
+
await this.runDuckDBQuery(`USE ${SHAREABLE_ATTACH_ALIAS}.main`);
|
|
195
|
+
this.attached = true;
|
|
196
|
+
}
|
|
197
|
+
buildInstanceOptions(opts) {
|
|
198
|
+
const forShareablePrimary = (opts === null || opts === void 0 ? void 0 : opts.forShareablePrimary) === true;
|
|
130
199
|
const options = {
|
|
131
200
|
custom_user_agent: `Malloy/${package_json_1.default.version}`,
|
|
132
201
|
};
|
|
133
202
|
if (this.normalized.motherDuckToken !== undefined) {
|
|
134
203
|
options['motherduck_token'] = this.normalized.motherDuckToken;
|
|
135
204
|
}
|
|
136
|
-
|
|
205
|
+
// In shareable mode the primary is :memory: and must stay writable —
|
|
206
|
+
// temp tables, manifestTemporaryTable, and search-index work all live
|
|
207
|
+
// there. The user's `readOnly` applies to the ATTACHed real file via
|
|
208
|
+
// `(READ_ONLY)` in attachIfShareable().
|
|
209
|
+
if (this.normalized.readOnly && !forShareablePrimary) {
|
|
137
210
|
options['access_mode'] = 'READ_ONLY';
|
|
138
211
|
}
|
|
139
212
|
if (this.normalized.autoloadKnownExtensions !== undefined) {
|
|
@@ -276,16 +349,40 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
276
349
|
}
|
|
277
350
|
}
|
|
278
351
|
async close() {
|
|
279
|
-
this.
|
|
352
|
+
if (this.normalized.effectiveShareable) {
|
|
353
|
+
await this.detachShareableFile();
|
|
354
|
+
if (this.ownedInstance) {
|
|
355
|
+
try {
|
|
356
|
+
this.ownedInstance.closeSync();
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
// Best effort during shutdown.
|
|
360
|
+
}
|
|
361
|
+
this.ownedInstance = null;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
this.detachInstance();
|
|
366
|
+
}
|
|
280
367
|
this.connection = null;
|
|
281
368
|
this.isSetup = undefined;
|
|
282
369
|
this.setupError = undefined;
|
|
370
|
+
this.attached = false;
|
|
283
371
|
this.closed = true;
|
|
284
372
|
}
|
|
285
373
|
async idle() {
|
|
286
374
|
// No-op for in-memory: closing the instance silently destroys state.
|
|
287
375
|
if (this.normalized.databasePath === ':memory:')
|
|
288
376
|
return;
|
|
377
|
+
if (this.normalized.effectiveShareable) {
|
|
378
|
+
// Shareable mode: keep the in-memory primary (and its temp tables,
|
|
379
|
+
// schema cache, etc.) alive; just DETACH the real file so the OS
|
|
380
|
+
// file lock is released. Next `setup()` re-runs `setupOnce()`, which
|
|
381
|
+
// re-ATTACHes lazily on first use.
|
|
382
|
+
await this.detachShareableFile();
|
|
383
|
+
this.isSetup = undefined;
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
289
386
|
this.detachInstance();
|
|
290
387
|
this.connection = null;
|
|
291
388
|
this.isSetup = undefined;
|
|
@@ -294,6 +391,23 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
294
391
|
// use and runs a fresh init() then. Doing it eagerly here would
|
|
295
392
|
// re-acquire the lock immediately and defeat the point of idling.
|
|
296
393
|
}
|
|
394
|
+
async detachShareableFile() {
|
|
395
|
+
if (!this.normalized.effectiveShareable)
|
|
396
|
+
return;
|
|
397
|
+
if (!this.attached || !this.connection)
|
|
398
|
+
return;
|
|
399
|
+
try {
|
|
400
|
+
await this.connection.run('USE memory.main');
|
|
401
|
+
await this.connection.run(`DETACH ${SHAREABLE_ATTACH_ALIAS}`);
|
|
402
|
+
this.attached = false;
|
|
403
|
+
}
|
|
404
|
+
catch {
|
|
405
|
+
// If DETACH fails the lock stays held; surfacing this error would
|
|
406
|
+
// mask the user's original op error. We leave `this.attached` as
|
|
407
|
+
// `true` so a later `attachIfShareable()` doesn't try to ATTACH on
|
|
408
|
+
// top of a still-attached alias.
|
|
409
|
+
}
|
|
410
|
+
}
|
|
297
411
|
/**
|
|
298
412
|
* Drop our entry from the shared `activeDBs` bookkeeping. If we were
|
|
299
413
|
* the last sharer, close the underlying `DuckDBInstance`.
|
package/dist/native.js
CHANGED
|
@@ -149,6 +149,16 @@ const duckdb_connection_1 = require("./duckdb_connection");
|
|
|
149
149
|
type: 'boolean',
|
|
150
150
|
optional: true,
|
|
151
151
|
},
|
|
152
|
+
{
|
|
153
|
+
name: 'shareable',
|
|
154
|
+
displayName: 'Shareable',
|
|
155
|
+
type: 'boolean',
|
|
156
|
+
optional: true,
|
|
157
|
+
description: 'When true, release the database file between operations so other ' +
|
|
158
|
+
'tools (malloy-cli, the duckdb CLI, another malloy host) can use ' +
|
|
159
|
+
'the same file while this connection is open. Adds a small ' +
|
|
160
|
+
'per-operation overhead. Default false.',
|
|
161
|
+
},
|
|
152
162
|
{
|
|
153
163
|
name: 'setupSQL',
|
|
154
164
|
displayName: 'Setup SQL',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@malloydata/db-duckdb",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.392",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"lint-fix": "eslint '**/*.ts{,x}' --fix",
|
|
54
54
|
"test": "jest --config=../../jest.config.js",
|
|
55
55
|
"build": "tsc --build",
|
|
56
|
+
"dev": "tsc --build",
|
|
56
57
|
"clean": "tsc --build --clean && rm -f tsconfig.tsbuildinfo",
|
|
57
58
|
"malloyc": "ts-node ../../scripts/malloy-to-json",
|
|
58
59
|
"prepublishOnly": "npm run build"
|
|
@@ -60,7 +61,7 @@
|
|
|
60
61
|
"dependencies": {
|
|
61
62
|
"@duckdb/duckdb-wasm": "1.33.1-dev13.0",
|
|
62
63
|
"@duckdb/node-api": "1.4.4-r.1",
|
|
63
|
-
"@malloydata/malloy": "0.0.
|
|
64
|
+
"@malloydata/malloy": "0.0.392",
|
|
64
65
|
"@motherduck/wasm-client": "^0.6.6",
|
|
65
66
|
"apache-arrow": "^17.0.0",
|
|
66
67
|
"web-worker": "^1.3.0"
|