@flowblade/sqlduck 0.15.0 → 0.16.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 +29 -29
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +125 -12
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -131,32 +131,32 @@ const queryResult = await dbDuckDbMemoryConn.query<{
|
|
|
131
131
|
### Node 24
|
|
132
132
|
|
|
133
133
|
```
|
|
134
|
-
RUN v4.1.
|
|
134
|
+
RUN v4.1.4 /home/sebastien/github/flowblade/packages/sqlduck
|
|
135
135
|
|
|
136
136
|
|
|
137
|
-
✓ bench/appender.bench.ts > appender benches
|
|
138
|
-
name hz min max mean p75 p99 p995 p999
|
|
139
|
-
· duckdb appender memory, count: 100000, chunk size 2048 2.
|
|
140
|
-
· duckdb appender file, count: 100000, chunk size 2048 1.
|
|
141
|
-
· duckdb appender, count: 100000, chunk size 1024
|
|
137
|
+
✓ bench/appender.bench.ts > appender benches 3412ms
|
|
138
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
139
|
+
· duckdb appender memory, count: 100000, chunk size 2048 2.8872 295.84 396.87 346.35 396.87 396.87 396.87 396.87 ±185.36% 2
|
|
140
|
+
· duckdb appender file, count: 100000, chunk size 2048 1.7908 558.40 558.40 558.40 558.40 558.40 558.40 558.40 ±0.00% 1
|
|
141
|
+
· duckdb appender, count: 100000, chunk size 1024 1.9967 500.82 500.82 500.82 500.82 500.82 500.82 500.82 ±0.00% 1
|
|
142
142
|
|
|
143
|
-
✓ bench/stream.bench.ts > Bench stream
|
|
144
|
-
name
|
|
145
|
-
· rowToColumnsChunk with chunkSize 2048 (count: 100000)
|
|
146
|
-
· mapFakeRowStream with chunkSize 2048 (count: 100000)
|
|
143
|
+
✓ bench/stream.bench.ts > Bench stream 2140ms
|
|
144
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
145
|
+
· rowToColumnsChunk with chunkSize 2048 (count: 100000) 11.8099 63.0430 172.82 84.6748 81.4757 172.82 172.82 172.82 ±27.12% 10
|
|
146
|
+
· mapFakeRowStream with chunkSize 2048 (count: 100000) 10.0442 79.5805 125.81 99.5603 112.35 125.81 125.81 125.81 ±12.04% 10
|
|
147
147
|
|
|
148
|
-
✓ bench/table-create.bench.ts > Bench getTableCreateFromZod
|
|
148
|
+
✓ bench/table-create.bench.ts > Bench getTableCreateFromZod 617ms
|
|
149
149
|
name hz min max mean p75 p99 p995 p999 rme samples
|
|
150
|
-
· getTableCreateFromZod
|
|
150
|
+
· getTableCreateFromZod 27,583.03 0.0226 2.7818 0.0363 0.0403 0.1185 0.1583 0.4321 ±1.66% 13792
|
|
151
151
|
|
|
152
152
|
BENCH Summary
|
|
153
153
|
|
|
154
154
|
duckdb appender memory, count: 100000, chunk size 2048 - bench/appender.bench.ts > appender benches
|
|
155
|
-
1.
|
|
156
|
-
1.
|
|
155
|
+
1.45x faster than duckdb appender, count: 100000, chunk size 1024
|
|
156
|
+
1.61x faster than duckdb appender file, count: 100000, chunk size 2048
|
|
157
157
|
|
|
158
158
|
rowToColumnsChunk with chunkSize 2048 (count: 100000) - bench/stream.bench.ts > Bench stream
|
|
159
|
-
1.
|
|
159
|
+
1.18x faster than mapFakeRowStream with chunkSize 2048 (count: 100000)
|
|
160
160
|
|
|
161
161
|
getTableCreateFromZod - bench/table-create.bench.ts > Bench getTableCreateFromZod
|
|
162
162
|
```
|
|
@@ -164,34 +164,34 @@ const queryResult = await dbDuckDbMemoryConn.query<{
|
|
|
164
164
|
### Bun 1.3.11
|
|
165
165
|
|
|
166
166
|
```
|
|
167
|
-
RUN v4.1.
|
|
167
|
+
RUN v4.1.4 /home/sebastien/github/flowblade/packages/sqlduck
|
|
168
168
|
|
|
169
169
|
|
|
170
|
-
✓ bench/appender.bench.ts > appender benches
|
|
170
|
+
✓ bench/appender.bench.ts > appender benches 3357ms
|
|
171
171
|
name hz min max mean p75 p99 p995 p999 rme samples
|
|
172
|
-
· duckdb appender memory, count: 100000, chunk size 2048 2.
|
|
173
|
-
· duckdb appender file, count: 100000, chunk size 2048 1.
|
|
174
|
-
· duckdb appender, count: 100000, chunk size 1024
|
|
172
|
+
· duckdb appender memory, count: 100000, chunk size 2048 2.9741 315.71 356.77 336.24 356.77 356.77 356.77 356.77 ±77.59% 2
|
|
173
|
+
· duckdb appender file, count: 100000, chunk size 2048 1.8953 527.62 527.62 527.62 527.62 527.62 527.62 527.62 ±0.00% 1
|
|
174
|
+
· duckdb appender, count: 100000, chunk size 1024 1.7803 561.70 561.70 561.70 561.70 561.70 561.70 561.70 ±0.00% 1
|
|
175
175
|
|
|
176
|
-
✓ bench/stream.bench.ts > Bench stream
|
|
177
|
-
name
|
|
178
|
-
· rowToColumnsChunk with chunkSize 2048 (count: 100000)
|
|
179
|
-
· mapFakeRowStream with chunkSize 2048 (count: 100000)
|
|
176
|
+
✓ bench/stream.bench.ts > Bench stream 2058ms
|
|
177
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
178
|
+
· rowToColumnsChunk with chunkSize 2048 (count: 100000) 12.0130 60.7081 111.32 83.2432 99.7116 111.32 111.32 111.32 ±14.15% 10
|
|
179
|
+
· mapFakeRowStream with chunkSize 2048 (count: 100000) 10.9710 76.4253 145.14 91.1493 91.1424 145.14 145.14 145.14 ±16.04% 10
|
|
180
180
|
|
|
181
|
-
✓ bench/table-create.bench.ts > Bench getTableCreateFromZod
|
|
181
|
+
✓ bench/table-create.bench.ts > Bench getTableCreateFromZod 621ms
|
|
182
182
|
name hz min max mean p75 p99 p995 p999 rme samples
|
|
183
|
-
· getTableCreateFromZod
|
|
183
|
+
· getTableCreateFromZod 27,472.91 0.0185 4.6226 0.0364 0.0369 0.1137 0.1476 1.9138 ±5.20% 13737
|
|
184
184
|
|
|
185
185
|
BENCH Summary
|
|
186
186
|
|
|
187
187
|
rowToColumnsChunk with chunkSize 2048 (count: 100000) - bench/stream.bench.ts > Bench stream
|
|
188
|
-
1.
|
|
188
|
+
1.09x faster than mapFakeRowStream with chunkSize 2048 (count: 100000)
|
|
189
189
|
|
|
190
190
|
getTableCreateFromZod - bench/table-create.bench.ts > Bench getTableCreateFromZod
|
|
191
191
|
|
|
192
192
|
duckdb appender memory, count: 100000, chunk size 2048 - bench/appender.bench.ts > appender benches
|
|
193
|
-
1.
|
|
194
|
-
1.
|
|
193
|
+
1.57x faster than duckdb appender file, count: 100000, chunk size 2048
|
|
194
|
+
1.67x faster than duckdb appender, count: 100000, chunk size 1024
|
|
195
195
|
|
|
196
196
|
```
|
|
197
197
|
|
package/dist/index.d.mts
CHANGED
|
@@ -81,7 +81,7 @@ declare class Table {
|
|
|
81
81
|
}
|
|
82
82
|
//#endregion
|
|
83
83
|
//#region src/table/table-schema-zod.type.d.ts
|
|
84
|
-
type ZodSchemaSupportedTypes = z.ZodString | z.ZodNumber | z.ZodInt | z.ZodInt32 | z.ZodUInt32 | z.ZodBigInt | z.ZodBoolean | z.ZodDate | z.ZodISODateTime | z.ZodISOTime | z.ZodISODate | z.ZodEmail | z.ZodURL | z.ZodUUID | z.ZodCUID | z.ZodCUID2 | z.ZodULID;
|
|
84
|
+
type ZodSchemaSupportedTypes = z.ZodString | z.ZodNumber | z.ZodInt | z.ZodInt32 | z.ZodUInt32 | z.ZodBigInt | z.ZodBoolean | z.ZodDate | z.ZodISODateTime | z.ZodISOTime | z.ZodISODate | z.ZodEmail | z.ZodURL | z.ZodUUID | z.ZodCUID | z.ZodCUID2 | z.ZodULID | z.ZodEnum;
|
|
85
85
|
type TableSchemaZod = z.ZodObject<Record<string, ZodSchemaSupportedTypes | z.ZodNullable<ZodSchemaSupportedTypes> | z.ZodCodec | z.ZodNullable<z.ZodCodec>>>;
|
|
86
86
|
//#endregion
|
|
87
87
|
//#region src/table/get-table-create-from-zod.d.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as duckReservedKeywords } from "./duck-reserved-keywords-B8XUjnaY.mjs";
|
|
2
2
|
import { n as assertValidAliasName, o as duckConnectionParamsZodSchema, s as duckValidatorsZod } from "./zod-CuPjTLv8.mjs";
|
|
3
|
-
import { BIGINT, BOOLEAN, DOUBLE, DuckDBDataChunk, DuckDBInstanceCache,
|
|
3
|
+
import { BIGINT, BOOLEAN, DOUBLE, DuckDBDataChunk, DuckDBInstanceCache, DuckDBTimestampMillisecondsValue, DuckDBTypeId, ENUM, FLOAT, HUGEINT, INTEGER, SMALLINT, TIMESTAMP, TIMESTAMP_MS, TINYINT, UBIGINT, UHUGEINT, UINTEGER, USMALLINT, UTINYINT, UUID, VARCHAR } from "@duckdb/node-api";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import { basename, dirname } from "node:path";
|
|
@@ -124,6 +124,110 @@ const createOnDataAppendedCollector = () => {
|
|
|
124
124
|
};
|
|
125
125
|
};
|
|
126
126
|
//#endregion
|
|
127
|
+
//#region src/converter/duck-value-converter.ts
|
|
128
|
+
const stringTimestampRegexp = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d{3,6})?Z?$/i;
|
|
129
|
+
const dateRegexp = /^\d{4}-\d{2}-\d{2}$/;
|
|
130
|
+
const createDuckValueConverterTypeError = (params) => {
|
|
131
|
+
let serializableValue;
|
|
132
|
+
try {
|
|
133
|
+
serializableValue = JSON.stringify(params.value);
|
|
134
|
+
} catch {
|
|
135
|
+
serializableValue = "<unserializable>";
|
|
136
|
+
}
|
|
137
|
+
return /* @__PURE__ */ new TypeError(`[DuckValueConverter.${params.method}]: Unsupported type ${typeof params.value} with value ${serializableValue}`);
|
|
138
|
+
};
|
|
139
|
+
var DuckValueConverter = class {
|
|
140
|
+
toUUID = (value) => {
|
|
141
|
+
if (typeof value === "bigint") return value;
|
|
142
|
+
else if (typeof value === "string") return BigInt("0x" + value.replaceAll("-", ""));
|
|
143
|
+
if (value === void 0 || value === null) return null;
|
|
144
|
+
throw createDuckValueConverterTypeError({
|
|
145
|
+
method: "toUUID",
|
|
146
|
+
value
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
toStringEnum = (value) => {
|
|
150
|
+
if (typeof value === "string") return value;
|
|
151
|
+
if (value === void 0 || value === null) return null;
|
|
152
|
+
throw createDuckValueConverterTypeError({
|
|
153
|
+
method: "toStringEnum",
|
|
154
|
+
value
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
toBigIntString = (value) => {
|
|
158
|
+
if (typeof value === "string") return value;
|
|
159
|
+
if (typeof value === "number" || typeof value === "bigint") return value.toString(10);
|
|
160
|
+
if (value === void 0 || value === null) return null;
|
|
161
|
+
throw createDuckValueConverterTypeError({
|
|
162
|
+
method: "toBigIntString",
|
|
163
|
+
value
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
toTimestampMs = (value) => {
|
|
167
|
+
if (value instanceof Date) return new DuckDBTimestampMillisecondsValue(BigInt(value.getTime()));
|
|
168
|
+
if (value === void 0 || value === null) return null;
|
|
169
|
+
if (typeof value === "string") {
|
|
170
|
+
const len = value.length;
|
|
171
|
+
if (len > 18 && len < 31 && stringTimestampRegexp.test(value)) {
|
|
172
|
+
const date = /* @__PURE__ */ new Date(value + (value.endsWith("Z") ? "" : "Z"));
|
|
173
|
+
return new DuckDBTimestampMillisecondsValue(BigInt(date.getTime()));
|
|
174
|
+
}
|
|
175
|
+
if (len === 10 && dateRegexp.test(value)) {
|
|
176
|
+
const date = /* @__PURE__ */ new Date(value + "T00:00:00Z");
|
|
177
|
+
return new DuckDBTimestampMillisecondsValue(BigInt(date.getTime()));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (typeof value === "bigint") return new DuckDBTimestampMillisecondsValue(value);
|
|
181
|
+
if (typeof value === "number") return new DuckDBTimestampMillisecondsValue(BigInt(value));
|
|
182
|
+
throw createDuckValueConverterTypeError({
|
|
183
|
+
method: "toTimestampMs",
|
|
184
|
+
value
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
//#endregion
|
|
189
|
+
//#region src/converter/create-duck-column-converters.ts
|
|
190
|
+
const createDuckColumnConverters = (duckTypes) => {
|
|
191
|
+
const convMap = /* @__PURE__ */ new Map();
|
|
192
|
+
const converter = new DuckValueConverter();
|
|
193
|
+
for (const [key, duckType] of Object.entries(duckTypes)) {
|
|
194
|
+
let conv;
|
|
195
|
+
const duckTypeId = duckType.typeId;
|
|
196
|
+
switch (duckTypeId) {
|
|
197
|
+
case DuckDBTypeId.TIMESTAMP_MS:
|
|
198
|
+
conv = converter.toTimestampMs;
|
|
199
|
+
break;
|
|
200
|
+
case DuckDBTypeId.BIGINT:
|
|
201
|
+
case DuckDBTypeId.UBIGINT:
|
|
202
|
+
case DuckDBTypeId.HUGEINT:
|
|
203
|
+
case DuckDBTypeId.UHUGEINT:
|
|
204
|
+
case DuckDBTypeId.INTEGER:
|
|
205
|
+
case DuckDBTypeId.UINTEGER:
|
|
206
|
+
case DuckDBTypeId.BIGNUM:
|
|
207
|
+
conv = converter.toBigIntString;
|
|
208
|
+
break;
|
|
209
|
+
case DuckDBTypeId.ENUM:
|
|
210
|
+
conv = converter.toStringEnum;
|
|
211
|
+
break;
|
|
212
|
+
case DuckDBTypeId.UUID:
|
|
213
|
+
conv = converter.toUUID;
|
|
214
|
+
break;
|
|
215
|
+
case DuckDBTypeId.BIT:
|
|
216
|
+
case DuckDBTypeId.BOOLEAN:
|
|
217
|
+
case DuckDBTypeId.TINYINT:
|
|
218
|
+
case DuckDBTypeId.USMALLINT:
|
|
219
|
+
case DuckDBTypeId.UTINYINT:
|
|
220
|
+
case DuckDBTypeId.VARCHAR:
|
|
221
|
+
case DuckDBTypeId.SMALLINT:
|
|
222
|
+
conv = false;
|
|
223
|
+
break;
|
|
224
|
+
default: throw new Error(`Unsupported duck type ${duckTypeId} / ${duckType.toString()} for column '${key}'`);
|
|
225
|
+
}
|
|
226
|
+
if (conv !== false) convMap.set(key, conv);
|
|
227
|
+
}
|
|
228
|
+
return convMap;
|
|
229
|
+
};
|
|
230
|
+
//#endregion
|
|
127
231
|
//#region src/config/flowblade-logtape-sqlduck.config.ts
|
|
128
232
|
const flowbladeLogtapeSqlduckConfig = { categories: ["flowblade", "sqlduck"] };
|
|
129
233
|
//#endregion
|
|
@@ -442,7 +546,10 @@ const createOptions = {
|
|
|
442
546
|
const duckDbTypesMap = new Map([
|
|
443
547
|
["VARCHAR", VARCHAR],
|
|
444
548
|
["BIGINT", BIGINT],
|
|
549
|
+
["UBIGINT", UBIGINT],
|
|
550
|
+
["HUGEINT", HUGEINT],
|
|
445
551
|
["TIMESTAMP", TIMESTAMP],
|
|
552
|
+
["TIMESTAMP_MS", TIMESTAMP_MS],
|
|
446
553
|
["UUID", UUID],
|
|
447
554
|
["BOOLEAN", BOOLEAN],
|
|
448
555
|
["INTEGER", INTEGER],
|
|
@@ -466,9 +573,10 @@ const getTableCreateFromZod = (params) => {
|
|
|
466
573
|
if (duckdbType !== void 0 && duckDbTypesMap.has(duckdbType)) c.duckdbType = duckDbTypesMap.get(duckdbType);
|
|
467
574
|
else switch (type) {
|
|
468
575
|
case "string":
|
|
469
|
-
|
|
576
|
+
if (Array.isArray(def.enum)) c.duckdbType = ENUM(def.enum);
|
|
577
|
+
else switch (format) {
|
|
470
578
|
case "date-time":
|
|
471
|
-
c.duckdbType =
|
|
579
|
+
c.duckdbType = TIMESTAMP_MS;
|
|
472
580
|
break;
|
|
473
581
|
case "int64":
|
|
474
582
|
c.duckdbType = BIGINT;
|
|
@@ -541,11 +649,6 @@ const createTableFromZod = async (params) => {
|
|
|
541
649
|
};
|
|
542
650
|
//#endregion
|
|
543
651
|
//#region src/utils/rows-to-columns-chunks.ts
|
|
544
|
-
const toDuckValue = (value) => {
|
|
545
|
-
if (value instanceof Date) return new DuckDBTimestampValue(BigInt(value.getTime() * 1e3));
|
|
546
|
-
if (typeof value === "bigint") return value.toString(10);
|
|
547
|
-
return value === void 0 ? null : value;
|
|
548
|
-
};
|
|
549
652
|
/**
|
|
550
653
|
* Similar to `rowsToColumns` but yields results in chunks to avoid buffering
|
|
551
654
|
* the entire dataset in memory. Each yielded item is a columns array for up to
|
|
@@ -556,14 +659,17 @@ const toDuckValue = (value) => {
|
|
|
556
659
|
* yields: [[['1','2'], ['A','B']], [['3'], ['C']]]
|
|
557
660
|
*/
|
|
558
661
|
async function* rowsToColumnsChunks(params) {
|
|
559
|
-
const { rows, chunkSize } = params;
|
|
662
|
+
const { rows, chunkSize, transformers } = params;
|
|
560
663
|
if (!Number.isSafeInteger(chunkSize) || chunkSize <= 0) throw new Error(`chunkSize must be a positive integer, got ${chunkSize}`);
|
|
561
664
|
const first = await rows.next();
|
|
562
665
|
if (first.done) return;
|
|
563
666
|
const keys = Object.keys(first.value);
|
|
564
667
|
let columns = keys.map(() => []);
|
|
565
668
|
let rowsInChunk = 0;
|
|
566
|
-
keys.forEach((k, i) =>
|
|
669
|
+
keys.forEach((k, i) => {
|
|
670
|
+
const fn = transformers?.get(k);
|
|
671
|
+
columns[i].push(fn === void 0 ? first.value[k] : fn(first.value[k]));
|
|
672
|
+
});
|
|
567
673
|
rowsInChunk++;
|
|
568
674
|
if (rowsInChunk >= chunkSize) {
|
|
569
675
|
yield columns;
|
|
@@ -571,7 +677,10 @@ async function* rowsToColumnsChunks(params) {
|
|
|
571
677
|
rowsInChunk = 0;
|
|
572
678
|
}
|
|
573
679
|
for await (const row of rows) {
|
|
574
|
-
keys.forEach((k, i) =>
|
|
680
|
+
keys.forEach((k, i) => {
|
|
681
|
+
const fn = transformers?.get(k);
|
|
682
|
+
columns[i].push(fn === void 0 ? row[k] : fn(row[k]));
|
|
683
|
+
});
|
|
575
684
|
rowsInChunk++;
|
|
576
685
|
if (rowsInChunk >= chunkSize) {
|
|
577
686
|
yield columns;
|
|
@@ -643,11 +752,15 @@ var SqlDuck = class {
|
|
|
643
752
|
});
|
|
644
753
|
const appender = await this.#conn.createAppender(table.tableName, table.schemaName, table.databaseName);
|
|
645
754
|
const chunkTypes = Array.from(columnTypes.values());
|
|
755
|
+
const transformers = createDuckColumnConverters(Object.fromEntries(Array.from(columnTypes).map(([key, duckType]) => {
|
|
756
|
+
return [key, duckType];
|
|
757
|
+
})));
|
|
646
758
|
let totalRows = 0;
|
|
647
759
|
const dataAppendedCollector = createOnDataAppendedCollector();
|
|
648
760
|
const columnStream = rowsToColumnsChunks({
|
|
649
761
|
rows: rowStream,
|
|
650
|
-
chunkSize
|
|
762
|
+
chunkSize,
|
|
763
|
+
transformers
|
|
651
764
|
});
|
|
652
765
|
let appendedChunkCount = 0;
|
|
653
766
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowblade/sqlduck",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"exports": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@logtape/logtape": "^2.0.5",
|
|
66
66
|
"@standard-schema/spec": "^1.1.0",
|
|
67
67
|
"is-safe-filename": "0.1.1",
|
|
68
|
-
"p-queue": "9.1.
|
|
68
|
+
"p-queue": "9.1.2",
|
|
69
69
|
"zod": "^4.3.6"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
@@ -93,8 +93,8 @@
|
|
|
93
93
|
"@typescript-eslint/eslint-plugin": "8.58.1",
|
|
94
94
|
"@typescript-eslint/parser": "8.58.1",
|
|
95
95
|
"@typescript/native-preview": "7.0.0-dev.20260406.1",
|
|
96
|
-
"@vitest/coverage-v8": "4.1.
|
|
97
|
-
"@vitest/ui": "4.1.
|
|
96
|
+
"@vitest/coverage-v8": "4.1.4",
|
|
97
|
+
"@vitest/ui": "4.1.4",
|
|
98
98
|
"ansis": "4.2.0",
|
|
99
99
|
"browserslist-to-esbuild": "2.1.1",
|
|
100
100
|
"core-js": "3.49.0",
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"typedoc-plugin-markdown": "4.11.0",
|
|
124
124
|
"typescript": "6.0.2",
|
|
125
125
|
"valibot": "1.3.1",
|
|
126
|
-
"vitest": "4.1.
|
|
126
|
+
"vitest": "4.1.4"
|
|
127
127
|
},
|
|
128
128
|
"files": [
|
|
129
129
|
"dist"
|