taladb 0.6.1 → 0.7.4
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/index.browser.mjs +62 -9
- package/dist/index.d.mts +55 -2
- package/dist/index.d.ts +55 -2
- package/dist/index.js +63 -9
- package/dist/index.mjs +62 -9
- package/package.json +1 -1
package/dist/index.browser.mjs
CHANGED
|
@@ -22,6 +22,52 @@ async function loadConfig(_configPath) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// src/index.ts
|
|
25
|
+
var TalaDbValidationError = class extends Error {
|
|
26
|
+
constructor(cause, context) {
|
|
27
|
+
const label = context ? ` (${context})` : "";
|
|
28
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
29
|
+
super(`TalaDB schema validation failed${label}: ${msg}`);
|
|
30
|
+
this.cause = cause;
|
|
31
|
+
this.name = "TalaDbValidationError";
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
function applySchema(col, options) {
|
|
35
|
+
const { schema, validateOnRead = false } = options;
|
|
36
|
+
if (!schema) return col;
|
|
37
|
+
function parseWrite(doc, label) {
|
|
38
|
+
try {
|
|
39
|
+
return schema.parse(doc);
|
|
40
|
+
} catch (err) {
|
|
41
|
+
throw new TalaDbValidationError(err, label);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function parseRead(doc) {
|
|
45
|
+
try {
|
|
46
|
+
return schema.parse(doc);
|
|
47
|
+
} catch (err) {
|
|
48
|
+
throw new TalaDbValidationError(err, "read");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
...col,
|
|
53
|
+
insert: async (doc) => {
|
|
54
|
+
parseWrite(doc, "insert");
|
|
55
|
+
return col.insert(doc);
|
|
56
|
+
},
|
|
57
|
+
insertMany: async (docs) => {
|
|
58
|
+
docs.forEach((doc, i) => parseWrite(doc, `insertMany[${i}]`));
|
|
59
|
+
return col.insertMany(docs);
|
|
60
|
+
},
|
|
61
|
+
find: validateOnRead ? async (filter) => {
|
|
62
|
+
const docs = await col.find(filter);
|
|
63
|
+
return docs.map((d) => parseRead(d));
|
|
64
|
+
} : col.find.bind(col),
|
|
65
|
+
findOne: validateOnRead ? async (filter) => {
|
|
66
|
+
const doc = await col.findOne(filter);
|
|
67
|
+
return doc === null ? null : parseRead(doc);
|
|
68
|
+
} : col.findOne.bind(col)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
25
71
|
function detectPlatform() {
|
|
26
72
|
if (globalThis.nativeCallSyncHook !== void 0) {
|
|
27
73
|
return "react-native";
|
|
@@ -92,9 +138,9 @@ async function createBrowserDB(dbName, config) {
|
|
|
92
138
|
}
|
|
93
139
|
};
|
|
94
140
|
}
|
|
95
|
-
function wrapCollection(name) {
|
|
141
|
+
function wrapCollection(name, opts) {
|
|
96
142
|
const s = JSON.stringify;
|
|
97
|
-
|
|
143
|
+
const wrapped = {
|
|
98
144
|
insert: (doc) => proxy.send("insert", { collection: name, docJson: s(doc) }),
|
|
99
145
|
insertMany: async (docs) => {
|
|
100
146
|
const json = await proxy.send("insertMany", {
|
|
@@ -200,9 +246,11 @@ async function createBrowserDB(dbName, config) {
|
|
|
200
246
|
};
|
|
201
247
|
}
|
|
202
248
|
};
|
|
249
|
+
return opts ? applySchema(wrapped, opts) : wrapped;
|
|
203
250
|
}
|
|
204
251
|
return {
|
|
205
|
-
collection: (name) => wrapCollection(name),
|
|
252
|
+
collection: (name, opts) => wrapCollection(name, opts),
|
|
253
|
+
compact: () => proxy.send("compact"),
|
|
206
254
|
close: async () => {
|
|
207
255
|
channel?.close();
|
|
208
256
|
await proxy.send("close");
|
|
@@ -214,9 +262,9 @@ async function createNodeDB(dbName, config) {
|
|
|
214
262
|
const { TalaDBNode } = await import("@taladb/node");
|
|
215
263
|
const configJson = config !== void 0 ? JSON.stringify(config) : null;
|
|
216
264
|
const db = TalaDBNode.open(dbName, configJson);
|
|
217
|
-
function wrapCollection(name) {
|
|
265
|
+
function wrapCollection(name, opts) {
|
|
218
266
|
const col = db.collection(name);
|
|
219
|
-
|
|
267
|
+
const wrapped = {
|
|
220
268
|
insert: async (doc) => col.insert(doc),
|
|
221
269
|
insertMany: async (docs) => col.insertMany(docs),
|
|
222
270
|
find: async (filter) => col.find(filter ?? null),
|
|
@@ -243,9 +291,11 @@ async function createNodeDB(dbName, config) {
|
|
|
243
291
|
},
|
|
244
292
|
subscribe: (filter, callback) => makePoller(async () => col.find(filter ?? null), callback)
|
|
245
293
|
};
|
|
294
|
+
return opts ? applySchema(wrapped, opts) : wrapped;
|
|
246
295
|
}
|
|
247
296
|
return {
|
|
248
|
-
collection: (name) => wrapCollection(name),
|
|
297
|
+
collection: (name, opts) => wrapCollection(name, opts),
|
|
298
|
+
compact: async () => db.compact(),
|
|
249
299
|
close: async () => {
|
|
250
300
|
}
|
|
251
301
|
};
|
|
@@ -258,9 +308,9 @@ async function createNativeDB(_dbName) {
|
|
|
258
308
|
);
|
|
259
309
|
}
|
|
260
310
|
const native = maybeNative;
|
|
261
|
-
function wrapCollection(name) {
|
|
311
|
+
function wrapCollection(name, opts) {
|
|
262
312
|
const col = native.collection(name);
|
|
263
|
-
|
|
313
|
+
const wrapped = {
|
|
264
314
|
insert: async (doc) => col.insert(doc),
|
|
265
315
|
insertMany: async (docs) => col.insertMany(docs),
|
|
266
316
|
find: async (filter) => col.find(filter ?? {}),
|
|
@@ -284,9 +334,11 @@ async function createNativeDB(_dbName) {
|
|
|
284
334
|
},
|
|
285
335
|
subscribe: (filter, callback) => makePoller(async () => col.find(filter ?? {}), callback)
|
|
286
336
|
};
|
|
337
|
+
return opts ? applySchema(wrapped, opts) : wrapped;
|
|
287
338
|
}
|
|
288
339
|
return {
|
|
289
|
-
collection: (name) => wrapCollection(name),
|
|
340
|
+
collection: (name, opts) => wrapCollection(name, opts),
|
|
341
|
+
compact: async () => native.compact(),
|
|
290
342
|
close: async () => native.close()
|
|
291
343
|
};
|
|
292
344
|
}
|
|
@@ -309,5 +361,6 @@ async function openDB(dbName = "taladb.db", options) {
|
|
|
309
361
|
}
|
|
310
362
|
}
|
|
311
363
|
export {
|
|
364
|
+
TalaDbValidationError,
|
|
312
365
|
openDB
|
|
313
366
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -80,6 +80,39 @@ type Update<T extends Document = Document> = {
|
|
|
80
80
|
[K in keyof T]?: Value;
|
|
81
81
|
};
|
|
82
82
|
};
|
|
83
|
+
/**
|
|
84
|
+
* A schema validator compatible with Zod, Valibot, and any library that
|
|
85
|
+
* exposes a `parse(data: unknown): T` method.
|
|
86
|
+
*
|
|
87
|
+
* @example with Zod
|
|
88
|
+
* const schema = z.object({ name: z.string(), age: z.number() });
|
|
89
|
+
* const users = db.collection<z.infer<typeof schema>>('users', { schema });
|
|
90
|
+
*
|
|
91
|
+
* @example with Valibot
|
|
92
|
+
* const schema = v.object({ name: v.string(), age: v.number() });
|
|
93
|
+
* const users = db.collection<v.InferOutput<typeof schema>>('users', { schema });
|
|
94
|
+
*/
|
|
95
|
+
interface Schema<T> {
|
|
96
|
+
parse(data: unknown): T;
|
|
97
|
+
}
|
|
98
|
+
/** Options passed to `db.collection()`. */
|
|
99
|
+
interface CollectionOptions<T extends Document = Document> {
|
|
100
|
+
/**
|
|
101
|
+
* Schema validator. When provided, every document passed to `insert` and
|
|
102
|
+
* `insertMany` is run through `schema.parse()` before being stored. If
|
|
103
|
+
* validation fails, a `TalaDbValidationError` is thrown.
|
|
104
|
+
*
|
|
105
|
+
* Compatible with Zod (`z.object({...})`), Valibot (`v.object({...})`), or
|
|
106
|
+
* any object with a `parse(data: unknown): T` method.
|
|
107
|
+
*/
|
|
108
|
+
schema?: Schema<T>;
|
|
109
|
+
/**
|
|
110
|
+
* When `true`, documents returned by `find` and `findOne` are also passed
|
|
111
|
+
* through `schema.parse()`. Useful for catching schema drift on old data.
|
|
112
|
+
* Defaults to `false`.
|
|
113
|
+
*/
|
|
114
|
+
validateOnRead?: boolean;
|
|
115
|
+
}
|
|
83
116
|
interface Collection<T extends Document = Document> {
|
|
84
117
|
insert(doc: Omit<T, '_id'>): Promise<string>;
|
|
85
118
|
insertMany(docs: Omit<T, '_id'>[]): Promise<string[]>;
|
|
@@ -166,7 +199,18 @@ interface Collection<T extends Document = Document> {
|
|
|
166
199
|
subscribe(filter: Filter<T>, callback: (docs: T[]) => void): () => void;
|
|
167
200
|
}
|
|
168
201
|
interface TalaDB {
|
|
169
|
-
collection<T extends Document = Document>(name: string): Collection<T>;
|
|
202
|
+
collection<T extends Document = Document>(name: string, options?: CollectionOptions<T>): Collection<T>;
|
|
203
|
+
/**
|
|
204
|
+
* Compact the underlying storage file, reclaiming space freed by deletes
|
|
205
|
+
* and updates.
|
|
206
|
+
*
|
|
207
|
+
* Call during idle periods — e.g. once on startup after `compactTombstones`.
|
|
208
|
+
* No-op on in-memory (IndexedDB-fallback) databases.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* await db.compact();
|
|
212
|
+
*/
|
|
213
|
+
compact(): Promise<void>;
|
|
170
214
|
close(): Promise<void>;
|
|
171
215
|
}
|
|
172
216
|
|
|
@@ -208,6 +252,15 @@ interface TalaDbConfig {
|
|
|
208
252
|
sync?: SyncConfig;
|
|
209
253
|
}
|
|
210
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Thrown when a document fails schema validation on `insert` or `insertMany`.
|
|
257
|
+
* The `cause` property holds the original error thrown by the schema library.
|
|
258
|
+
*/
|
|
259
|
+
declare class TalaDbValidationError extends Error {
|
|
260
|
+
readonly cause: unknown;
|
|
261
|
+
constructor(cause: unknown, context?: string);
|
|
262
|
+
}
|
|
263
|
+
|
|
211
264
|
/** Options for `openDB`. */
|
|
212
265
|
interface OpenDBOptions {
|
|
213
266
|
/**
|
|
@@ -241,4 +294,4 @@ interface OpenDBOptions {
|
|
|
241
294
|
*/
|
|
242
295
|
declare function openDB(dbName?: string, options?: OpenDBOptions): Promise<TalaDB>;
|
|
243
296
|
|
|
244
|
-
export { type Collection, type CollectionIndexInfo, type Document, type Filter, type OpenDBOptions, type SyncConfig, type TalaDB, type TalaDbConfig, type Update, type Value, type VectorIndexOptions, type VectorMetric, type VectorSearchResult, openDB };
|
|
297
|
+
export { type Collection, type CollectionIndexInfo, type CollectionOptions, type Document, type Filter, type OpenDBOptions, type Schema, type SyncConfig, type TalaDB, type TalaDbConfig, TalaDbValidationError, type Update, type Value, type VectorIndexOptions, type VectorMetric, type VectorSearchResult, openDB };
|
package/dist/index.d.ts
CHANGED
|
@@ -80,6 +80,39 @@ type Update<T extends Document = Document> = {
|
|
|
80
80
|
[K in keyof T]?: Value;
|
|
81
81
|
};
|
|
82
82
|
};
|
|
83
|
+
/**
|
|
84
|
+
* A schema validator compatible with Zod, Valibot, and any library that
|
|
85
|
+
* exposes a `parse(data: unknown): T` method.
|
|
86
|
+
*
|
|
87
|
+
* @example with Zod
|
|
88
|
+
* const schema = z.object({ name: z.string(), age: z.number() });
|
|
89
|
+
* const users = db.collection<z.infer<typeof schema>>('users', { schema });
|
|
90
|
+
*
|
|
91
|
+
* @example with Valibot
|
|
92
|
+
* const schema = v.object({ name: v.string(), age: v.number() });
|
|
93
|
+
* const users = db.collection<v.InferOutput<typeof schema>>('users', { schema });
|
|
94
|
+
*/
|
|
95
|
+
interface Schema<T> {
|
|
96
|
+
parse(data: unknown): T;
|
|
97
|
+
}
|
|
98
|
+
/** Options passed to `db.collection()`. */
|
|
99
|
+
interface CollectionOptions<T extends Document = Document> {
|
|
100
|
+
/**
|
|
101
|
+
* Schema validator. When provided, every document passed to `insert` and
|
|
102
|
+
* `insertMany` is run through `schema.parse()` before being stored. If
|
|
103
|
+
* validation fails, a `TalaDbValidationError` is thrown.
|
|
104
|
+
*
|
|
105
|
+
* Compatible with Zod (`z.object({...})`), Valibot (`v.object({...})`), or
|
|
106
|
+
* any object with a `parse(data: unknown): T` method.
|
|
107
|
+
*/
|
|
108
|
+
schema?: Schema<T>;
|
|
109
|
+
/**
|
|
110
|
+
* When `true`, documents returned by `find` and `findOne` are also passed
|
|
111
|
+
* through `schema.parse()`. Useful for catching schema drift on old data.
|
|
112
|
+
* Defaults to `false`.
|
|
113
|
+
*/
|
|
114
|
+
validateOnRead?: boolean;
|
|
115
|
+
}
|
|
83
116
|
interface Collection<T extends Document = Document> {
|
|
84
117
|
insert(doc: Omit<T, '_id'>): Promise<string>;
|
|
85
118
|
insertMany(docs: Omit<T, '_id'>[]): Promise<string[]>;
|
|
@@ -166,7 +199,18 @@ interface Collection<T extends Document = Document> {
|
|
|
166
199
|
subscribe(filter: Filter<T>, callback: (docs: T[]) => void): () => void;
|
|
167
200
|
}
|
|
168
201
|
interface TalaDB {
|
|
169
|
-
collection<T extends Document = Document>(name: string): Collection<T>;
|
|
202
|
+
collection<T extends Document = Document>(name: string, options?: CollectionOptions<T>): Collection<T>;
|
|
203
|
+
/**
|
|
204
|
+
* Compact the underlying storage file, reclaiming space freed by deletes
|
|
205
|
+
* and updates.
|
|
206
|
+
*
|
|
207
|
+
* Call during idle periods — e.g. once on startup after `compactTombstones`.
|
|
208
|
+
* No-op on in-memory (IndexedDB-fallback) databases.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* await db.compact();
|
|
212
|
+
*/
|
|
213
|
+
compact(): Promise<void>;
|
|
170
214
|
close(): Promise<void>;
|
|
171
215
|
}
|
|
172
216
|
|
|
@@ -208,6 +252,15 @@ interface TalaDbConfig {
|
|
|
208
252
|
sync?: SyncConfig;
|
|
209
253
|
}
|
|
210
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Thrown when a document fails schema validation on `insert` or `insertMany`.
|
|
257
|
+
* The `cause` property holds the original error thrown by the schema library.
|
|
258
|
+
*/
|
|
259
|
+
declare class TalaDbValidationError extends Error {
|
|
260
|
+
readonly cause: unknown;
|
|
261
|
+
constructor(cause: unknown, context?: string);
|
|
262
|
+
}
|
|
263
|
+
|
|
211
264
|
/** Options for `openDB`. */
|
|
212
265
|
interface OpenDBOptions {
|
|
213
266
|
/**
|
|
@@ -241,4 +294,4 @@ interface OpenDBOptions {
|
|
|
241
294
|
*/
|
|
242
295
|
declare function openDB(dbName?: string, options?: OpenDBOptions): Promise<TalaDB>;
|
|
243
296
|
|
|
244
|
-
export { type Collection, type CollectionIndexInfo, type Document, type Filter, type OpenDBOptions, type SyncConfig, type TalaDB, type TalaDbConfig, type Update, type Value, type VectorIndexOptions, type VectorMetric, type VectorSearchResult, openDB };
|
|
297
|
+
export { type Collection, type CollectionIndexInfo, type CollectionOptions, type Document, type Filter, type OpenDBOptions, type Schema, type SyncConfig, type TalaDB, type TalaDbConfig, TalaDbValidationError, type Update, type Value, type VectorIndexOptions, type VectorMetric, type VectorSearchResult, openDB };
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
TalaDbValidationError: () => TalaDbValidationError,
|
|
33
34
|
openDB: () => openDB
|
|
34
35
|
});
|
|
35
36
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -103,6 +104,52 @@ async function loadConfig(configPath) {
|
|
|
103
104
|
|
|
104
105
|
// src/index.ts
|
|
105
106
|
var import_meta = {};
|
|
107
|
+
var TalaDbValidationError = class extends Error {
|
|
108
|
+
constructor(cause, context) {
|
|
109
|
+
const label = context ? ` (${context})` : "";
|
|
110
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
111
|
+
super(`TalaDB schema validation failed${label}: ${msg}`);
|
|
112
|
+
this.cause = cause;
|
|
113
|
+
this.name = "TalaDbValidationError";
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
function applySchema(col, options) {
|
|
117
|
+
const { schema, validateOnRead = false } = options;
|
|
118
|
+
if (!schema) return col;
|
|
119
|
+
function parseWrite(doc, label) {
|
|
120
|
+
try {
|
|
121
|
+
return schema.parse(doc);
|
|
122
|
+
} catch (err) {
|
|
123
|
+
throw new TalaDbValidationError(err, label);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function parseRead(doc) {
|
|
127
|
+
try {
|
|
128
|
+
return schema.parse(doc);
|
|
129
|
+
} catch (err) {
|
|
130
|
+
throw new TalaDbValidationError(err, "read");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
...col,
|
|
135
|
+
insert: async (doc) => {
|
|
136
|
+
parseWrite(doc, "insert");
|
|
137
|
+
return col.insert(doc);
|
|
138
|
+
},
|
|
139
|
+
insertMany: async (docs) => {
|
|
140
|
+
docs.forEach((doc, i) => parseWrite(doc, `insertMany[${i}]`));
|
|
141
|
+
return col.insertMany(docs);
|
|
142
|
+
},
|
|
143
|
+
find: validateOnRead ? async (filter) => {
|
|
144
|
+
const docs = await col.find(filter);
|
|
145
|
+
return docs.map((d) => parseRead(d));
|
|
146
|
+
} : col.find.bind(col),
|
|
147
|
+
findOne: validateOnRead ? async (filter) => {
|
|
148
|
+
const doc = await col.findOne(filter);
|
|
149
|
+
return doc === null ? null : parseRead(doc);
|
|
150
|
+
} : col.findOne.bind(col)
|
|
151
|
+
};
|
|
152
|
+
}
|
|
106
153
|
function detectPlatform() {
|
|
107
154
|
if (globalThis.nativeCallSyncHook !== void 0) {
|
|
108
155
|
return "react-native";
|
|
@@ -173,9 +220,9 @@ async function createBrowserDB(dbName, config) {
|
|
|
173
220
|
}
|
|
174
221
|
};
|
|
175
222
|
}
|
|
176
|
-
function wrapCollection(name) {
|
|
223
|
+
function wrapCollection(name, opts) {
|
|
177
224
|
const s = JSON.stringify;
|
|
178
|
-
|
|
225
|
+
const wrapped = {
|
|
179
226
|
insert: (doc) => proxy.send("insert", { collection: name, docJson: s(doc) }),
|
|
180
227
|
insertMany: async (docs) => {
|
|
181
228
|
const json = await proxy.send("insertMany", {
|
|
@@ -281,9 +328,11 @@ async function createBrowserDB(dbName, config) {
|
|
|
281
328
|
};
|
|
282
329
|
}
|
|
283
330
|
};
|
|
331
|
+
return opts ? applySchema(wrapped, opts) : wrapped;
|
|
284
332
|
}
|
|
285
333
|
return {
|
|
286
|
-
collection: (name) => wrapCollection(name),
|
|
334
|
+
collection: (name, opts) => wrapCollection(name, opts),
|
|
335
|
+
compact: () => proxy.send("compact"),
|
|
287
336
|
close: async () => {
|
|
288
337
|
channel?.close();
|
|
289
338
|
await proxy.send("close");
|
|
@@ -295,9 +344,9 @@ async function createNodeDB(dbName, config) {
|
|
|
295
344
|
const { TalaDBNode } = await import("@taladb/node");
|
|
296
345
|
const configJson = config !== void 0 ? JSON.stringify(config) : null;
|
|
297
346
|
const db = TalaDBNode.open(dbName, configJson);
|
|
298
|
-
function wrapCollection(name) {
|
|
347
|
+
function wrapCollection(name, opts) {
|
|
299
348
|
const col = db.collection(name);
|
|
300
|
-
|
|
349
|
+
const wrapped = {
|
|
301
350
|
insert: async (doc) => col.insert(doc),
|
|
302
351
|
insertMany: async (docs) => col.insertMany(docs),
|
|
303
352
|
find: async (filter) => col.find(filter ?? null),
|
|
@@ -324,9 +373,11 @@ async function createNodeDB(dbName, config) {
|
|
|
324
373
|
},
|
|
325
374
|
subscribe: (filter, callback) => makePoller(async () => col.find(filter ?? null), callback)
|
|
326
375
|
};
|
|
376
|
+
return opts ? applySchema(wrapped, opts) : wrapped;
|
|
327
377
|
}
|
|
328
378
|
return {
|
|
329
|
-
collection: (name) => wrapCollection(name),
|
|
379
|
+
collection: (name, opts) => wrapCollection(name, opts),
|
|
380
|
+
compact: async () => db.compact(),
|
|
330
381
|
close: async () => {
|
|
331
382
|
}
|
|
332
383
|
};
|
|
@@ -339,9 +390,9 @@ async function createNativeDB(_dbName) {
|
|
|
339
390
|
);
|
|
340
391
|
}
|
|
341
392
|
const native = maybeNative;
|
|
342
|
-
function wrapCollection(name) {
|
|
393
|
+
function wrapCollection(name, opts) {
|
|
343
394
|
const col = native.collection(name);
|
|
344
|
-
|
|
395
|
+
const wrapped = {
|
|
345
396
|
insert: async (doc) => col.insert(doc),
|
|
346
397
|
insertMany: async (docs) => col.insertMany(docs),
|
|
347
398
|
find: async (filter) => col.find(filter ?? {}),
|
|
@@ -365,9 +416,11 @@ async function createNativeDB(_dbName) {
|
|
|
365
416
|
},
|
|
366
417
|
subscribe: (filter, callback) => makePoller(async () => col.find(filter ?? {}), callback)
|
|
367
418
|
};
|
|
419
|
+
return opts ? applySchema(wrapped, opts) : wrapped;
|
|
368
420
|
}
|
|
369
421
|
return {
|
|
370
|
-
collection: (name) => wrapCollection(name),
|
|
422
|
+
collection: (name, opts) => wrapCollection(name, opts),
|
|
423
|
+
compact: async () => native.compact(),
|
|
371
424
|
close: async () => native.close()
|
|
372
425
|
};
|
|
373
426
|
}
|
|
@@ -391,5 +444,6 @@ async function openDB(dbName = "taladb.db", options) {
|
|
|
391
444
|
}
|
|
392
445
|
// Annotate the CommonJS export names for ESM import in node:
|
|
393
446
|
0 && (module.exports = {
|
|
447
|
+
TalaDbValidationError,
|
|
394
448
|
openDB
|
|
395
449
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -66,6 +66,52 @@ async function loadConfig(configPath) {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
// src/index.ts
|
|
69
|
+
var TalaDbValidationError = class extends Error {
|
|
70
|
+
constructor(cause, context) {
|
|
71
|
+
const label = context ? ` (${context})` : "";
|
|
72
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
73
|
+
super(`TalaDB schema validation failed${label}: ${msg}`);
|
|
74
|
+
this.cause = cause;
|
|
75
|
+
this.name = "TalaDbValidationError";
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
function applySchema(col, options) {
|
|
79
|
+
const { schema, validateOnRead = false } = options;
|
|
80
|
+
if (!schema) return col;
|
|
81
|
+
function parseWrite(doc, label) {
|
|
82
|
+
try {
|
|
83
|
+
return schema.parse(doc);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
throw new TalaDbValidationError(err, label);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function parseRead(doc) {
|
|
89
|
+
try {
|
|
90
|
+
return schema.parse(doc);
|
|
91
|
+
} catch (err) {
|
|
92
|
+
throw new TalaDbValidationError(err, "read");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
...col,
|
|
97
|
+
insert: async (doc) => {
|
|
98
|
+
parseWrite(doc, "insert");
|
|
99
|
+
return col.insert(doc);
|
|
100
|
+
},
|
|
101
|
+
insertMany: async (docs) => {
|
|
102
|
+
docs.forEach((doc, i) => parseWrite(doc, `insertMany[${i}]`));
|
|
103
|
+
return col.insertMany(docs);
|
|
104
|
+
},
|
|
105
|
+
find: validateOnRead ? async (filter) => {
|
|
106
|
+
const docs = await col.find(filter);
|
|
107
|
+
return docs.map((d) => parseRead(d));
|
|
108
|
+
} : col.find.bind(col),
|
|
109
|
+
findOne: validateOnRead ? async (filter) => {
|
|
110
|
+
const doc = await col.findOne(filter);
|
|
111
|
+
return doc === null ? null : parseRead(doc);
|
|
112
|
+
} : col.findOne.bind(col)
|
|
113
|
+
};
|
|
114
|
+
}
|
|
69
115
|
function detectPlatform() {
|
|
70
116
|
if (globalThis.nativeCallSyncHook !== void 0) {
|
|
71
117
|
return "react-native";
|
|
@@ -136,9 +182,9 @@ async function createBrowserDB(dbName, config) {
|
|
|
136
182
|
}
|
|
137
183
|
};
|
|
138
184
|
}
|
|
139
|
-
function wrapCollection(name) {
|
|
185
|
+
function wrapCollection(name, opts) {
|
|
140
186
|
const s = JSON.stringify;
|
|
141
|
-
|
|
187
|
+
const wrapped = {
|
|
142
188
|
insert: (doc) => proxy.send("insert", { collection: name, docJson: s(doc) }),
|
|
143
189
|
insertMany: async (docs) => {
|
|
144
190
|
const json = await proxy.send("insertMany", {
|
|
@@ -244,9 +290,11 @@ async function createBrowserDB(dbName, config) {
|
|
|
244
290
|
};
|
|
245
291
|
}
|
|
246
292
|
};
|
|
293
|
+
return opts ? applySchema(wrapped, opts) : wrapped;
|
|
247
294
|
}
|
|
248
295
|
return {
|
|
249
|
-
collection: (name) => wrapCollection(name),
|
|
296
|
+
collection: (name, opts) => wrapCollection(name, opts),
|
|
297
|
+
compact: () => proxy.send("compact"),
|
|
250
298
|
close: async () => {
|
|
251
299
|
channel?.close();
|
|
252
300
|
await proxy.send("close");
|
|
@@ -258,9 +306,9 @@ async function createNodeDB(dbName, config) {
|
|
|
258
306
|
const { TalaDBNode } = await import("@taladb/node");
|
|
259
307
|
const configJson = config !== void 0 ? JSON.stringify(config) : null;
|
|
260
308
|
const db = TalaDBNode.open(dbName, configJson);
|
|
261
|
-
function wrapCollection(name) {
|
|
309
|
+
function wrapCollection(name, opts) {
|
|
262
310
|
const col = db.collection(name);
|
|
263
|
-
|
|
311
|
+
const wrapped = {
|
|
264
312
|
insert: async (doc) => col.insert(doc),
|
|
265
313
|
insertMany: async (docs) => col.insertMany(docs),
|
|
266
314
|
find: async (filter) => col.find(filter ?? null),
|
|
@@ -287,9 +335,11 @@ async function createNodeDB(dbName, config) {
|
|
|
287
335
|
},
|
|
288
336
|
subscribe: (filter, callback) => makePoller(async () => col.find(filter ?? null), callback)
|
|
289
337
|
};
|
|
338
|
+
return opts ? applySchema(wrapped, opts) : wrapped;
|
|
290
339
|
}
|
|
291
340
|
return {
|
|
292
|
-
collection: (name) => wrapCollection(name),
|
|
341
|
+
collection: (name, opts) => wrapCollection(name, opts),
|
|
342
|
+
compact: async () => db.compact(),
|
|
293
343
|
close: async () => {
|
|
294
344
|
}
|
|
295
345
|
};
|
|
@@ -302,9 +352,9 @@ async function createNativeDB(_dbName) {
|
|
|
302
352
|
);
|
|
303
353
|
}
|
|
304
354
|
const native = maybeNative;
|
|
305
|
-
function wrapCollection(name) {
|
|
355
|
+
function wrapCollection(name, opts) {
|
|
306
356
|
const col = native.collection(name);
|
|
307
|
-
|
|
357
|
+
const wrapped = {
|
|
308
358
|
insert: async (doc) => col.insert(doc),
|
|
309
359
|
insertMany: async (docs) => col.insertMany(docs),
|
|
310
360
|
find: async (filter) => col.find(filter ?? {}),
|
|
@@ -328,9 +378,11 @@ async function createNativeDB(_dbName) {
|
|
|
328
378
|
},
|
|
329
379
|
subscribe: (filter, callback) => makePoller(async () => col.find(filter ?? {}), callback)
|
|
330
380
|
};
|
|
381
|
+
return opts ? applySchema(wrapped, opts) : wrapped;
|
|
331
382
|
}
|
|
332
383
|
return {
|
|
333
|
-
collection: (name) => wrapCollection(name),
|
|
384
|
+
collection: (name, opts) => wrapCollection(name, opts),
|
|
385
|
+
compact: async () => native.compact(),
|
|
334
386
|
close: async () => native.close()
|
|
335
387
|
};
|
|
336
388
|
}
|
|
@@ -353,5 +405,6 @@ async function openDB(dbName = "taladb.db", options) {
|
|
|
353
405
|
}
|
|
354
406
|
}
|
|
355
407
|
export {
|
|
408
|
+
TalaDbValidationError,
|
|
356
409
|
openDB
|
|
357
410
|
};
|