document-dataply 0.0.2-alpha.2 → 0.0.2

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.
@@ -4,7 +4,7 @@ import { DocumentDataplyAPI } from '../document';
4
4
  export declare class DocumentSerializeStrategyAsync<T extends Primitive> extends SerializeStrategyAsync<number, DataplyTreeValue<T>> {
5
5
  protected readonly api: DocumentDataplyAPI<any>;
6
6
  protected readonly txContext: DocumentDataplyAPI<any>['txContext'];
7
- protected readonly treeKey: string;
7
+ readonly treeKey: string;
8
8
  constructor(order: number, api: DocumentDataplyAPI<any>, txContext: DocumentDataplyAPI<any>['txContext'], treeKey: string);
9
9
  id(isLeaf: boolean): Promise<string>;
10
10
  read(id: string): Promise<BPTreeNode<number, DataplyTreeValue<T>>>;
@@ -1,14 +1,27 @@
1
- import type { DataplyTreeValue, DocumentDataplyInnerMetadata, DocumentDataplyOptions, DocumentJSON, FlattenedDocumentJSON, Primitive, DocumentDataplyQuery, FinalFlatten, DocumentDataplyCondition, DataplyDocument, DocumentDataplyMetadata } from '../types';
1
+ import type { DataplyTreeValue, DocumentDataplyInnerMetadata, DocumentDataplyOptions, DocumentJSON, FlattenedDocumentJSON, Primitive, DocumentDataplyQuery, FinalFlatten, DocumentDataplyCondition, DataplyDocument, DocumentDataplyMetadata, DocumentDataplyQueryOptions, IndexedDocumentDataplyQuery } from '../types';
2
2
  import { DataplyAPI, Transaction, BPTreeAsync } from 'dataply';
3
3
  import { DocumentValueComparator } from './bptree/documentComparator';
4
4
  export declare class DocumentDataplyAPI<T extends DocumentJSON> extends DataplyAPI {
5
5
  runWithDefault: <T_1>(callback: (tx: Transaction) => Promise<T_1>, tx?: Transaction) => Promise<T_1>;
6
- treeHeads: DocumentDataplyInnerMetadata['treeHeads'];
6
+ streamWithDefault: <T_1>(callback: (tx: Transaction) => AsyncGenerator<T_1>, tx?: Transaction) => AsyncGenerator<T_1>;
7
+ indices: DocumentDataplyInnerMetadata['indices'];
7
8
  readonly trees: Map<string, BPTreeAsync<number, DataplyTreeValue<Primitive>>>;
8
9
  readonly comparator: DocumentValueComparator<DataplyTreeValue<Primitive>, Primitive>;
9
- constructor(file: string, options: DocumentDataplyOptions);
10
- ensureTree<T extends Primitive>(field: string): Promise<BPTreeAsync<number, DataplyTreeValue<T>>>;
11
- createDocumentMetadata(): DocumentDataplyInnerMetadata;
10
+ private pendingBackfillFields;
11
+ private readonly lock;
12
+ constructor(file: string, options: DocumentDataplyOptions<T>);
13
+ readLock<T>(fn: () => T): Promise<T>;
14
+ writeLock<T>(fn: () => T): Promise<T>;
15
+ getDocument(pk: number, tx?: Transaction): Promise<DataplyDocument<T>>;
16
+ /**
17
+ * Backfill indices for fields that were added with `true` option after data was inserted.
18
+ * This method should be called after `init()` if you want to index existing documents
19
+ * for newly added index fields.
20
+ *
21
+ * @returns Number of documents that were backfilled
22
+ */
23
+ backfillIndices(tx?: Transaction): Promise<number>;
24
+ createDocumentInnerMetadata(indices: DocumentDataplyInnerMetadata['indices']): DocumentDataplyInnerMetadata;
12
25
  initializeDocumentFile(tx: Transaction): Promise<void>;
13
26
  verifyDocumentFile(tx: Transaction): Promise<boolean>;
14
27
  /**
@@ -20,12 +33,12 @@ export declare class DocumentDataplyAPI<T extends DocumentJSON> extends DataplyA
20
33
  getDocumentMetadata(tx: Transaction): Promise<DocumentDataplyMetadata>;
21
34
  getDocumentInnerMetadata(tx: Transaction): Promise<DocumentDataplyInnerMetadata>;
22
35
  updateDocumentInnerMetadata(metadata: DocumentDataplyInnerMetadata, tx: Transaction): Promise<void>;
23
- updateTreeHead(tx: Transaction): Promise<void>;
24
36
  }
25
- export declare class DocumentDataply<T extends DocumentJSON> {
37
+ export declare class DocumentDataply<T extends DocumentJSON, I extends string = keyof FinalFlatten<T> & string> {
26
38
  protected readonly api: DocumentDataplyAPI<T>;
39
+ private readonly indexedFields;
27
40
  private readonly operatorConverters;
28
- constructor(file: string, options?: DocumentDataplyOptions);
41
+ constructor(file: string, options?: DocumentDataplyOptions<T>);
29
42
  /**
30
43
  * Initialize the document database
31
44
  */
@@ -41,17 +54,20 @@ export declare class DocumentDataply<T extends DocumentJSON> {
41
54
  private verboseQuery;
42
55
  /**
43
56
  * Get the selectivity candidate for the given query
44
- * @param query
45
- * @returns
57
+ * @param query The query conditions
58
+ * @param orderByField Optional field name for orderBy optimization
59
+ * @returns Driver and other candidates for query execution
46
60
  */
47
- getSelectivityCandidate<U extends FinalFlatten<DataplyDocument<T>>, V extends DataplyTreeValue<U>>(query: Partial<DocumentDataplyQuery<V>>): Promise<{
61
+ getSelectivityCandidate<U extends Partial<IndexedDocumentDataplyQuery<FinalFlatten<DataplyDocument<T>>, I>>, V extends DataplyTreeValue<U>>(query: Partial<DocumentDataplyQuery<V>>, orderByField?: string): Promise<{
48
62
  driver: {
49
63
  tree: BPTreeAsync<number, V>;
50
64
  condition: Partial<DocumentDataplyCondition<U>>;
65
+ field: string;
51
66
  };
52
67
  others: {
53
68
  tree: BPTreeAsync<number, V>;
54
69
  condition: Partial<DocumentDataplyCondition<U>>;
70
+ field: string;
55
71
  }[];
56
72
  } | null>;
57
73
  private insertDocument;
@@ -59,17 +75,28 @@ export declare class DocumentDataply<T extends DocumentJSON> {
59
75
  * Insert a document into the database
60
76
  * @param document The document to insert
61
77
  * @param tx The transaction to use
62
- * @returns True if the document was inserted successfully
78
+ * @returns The primary key of the inserted document
79
+ */
80
+ insert(document: T, tx?: Transaction): Promise<number>;
81
+ /**
82
+ * Insert a batch of documents into the database
83
+ * @param documents The documents to insert
84
+ * @param tx The transaction to use
85
+ * @returns The primary keys of the inserted documents
63
86
  */
64
- insert(document: T, tx?: Transaction): Promise<boolean>;
87
+ insertBatch(documents: T[], tx?: Transaction): Promise<number[]>;
65
88
  /**
66
89
  * Select documents from the database
67
- * @param query The query to use
68
- * @param limit The maximum number of documents to return
90
+ * @param query The query to use (only indexed fields + _id allowed)
91
+ * @param options The options to use
69
92
  * @param tx The transaction to use
70
93
  * @returns The documents that match the query
94
+ * @throws Error if query or orderBy contains non-indexed fields
71
95
  */
72
- select(query: Partial<DocumentDataplyQuery<FinalFlatten<DataplyDocument<T>>>>, limit?: number, tx?: Transaction): Promise<DataplyDocument<T>[]>;
96
+ select(query: Partial<IndexedDocumentDataplyQuery<FinalFlatten<DataplyDocument<T>>, I>>, options?: DocumentDataplyQueryOptions<FinalFlatten<DataplyDocument<T>>, I>, tx?: Transaction): {
97
+ stream: AsyncIterableIterator<DataplyDocument<T>>;
98
+ drain: () => Promise<DataplyDocument<T>[]>;
99
+ };
73
100
  /**
74
101
  * Close the document database
75
102
  */
@@ -1,4 +1,4 @@
1
- import type { DataplyOptions, SerializeStrategyHead } from 'dataply';
1
+ import type { BPTreeOrder, DataplyOptions } from 'dataply';
2
2
  export type Primitive = string | number | boolean | null;
3
3
  export type JSONValue = Primitive | JSONValue[] | {
4
4
  [key: string]: JSONValue;
@@ -15,7 +15,9 @@ export interface DocumentDataplyInnerMetadata {
15
15
  createdAt: number;
16
16
  updatedAt: number;
17
17
  lastId: number;
18
- treeHeads: Record<string, SerializeStrategyHead>;
18
+ indices: {
19
+ [key: string]: [number, boolean];
20
+ };
19
21
  }
20
22
  export interface DocumentDataplyMetadata {
21
23
  /**
@@ -42,14 +44,25 @@ export type DocumentDataplyCondition<V> = {
42
44
  gte?: Partial<V>;
43
45
  equal?: Partial<V>;
44
46
  notEqual?: Partial<V>;
45
- like?: Partial<V>;
46
47
  or?: Partial<V>[];
48
+ like?: string;
49
+ };
50
+ export type DocumentDataplyQueryOptions<V, I extends string = string> = {
51
+ limit?: number;
52
+ orderBy?: I | '_id';
53
+ sortOrder?: BPTreeOrder;
47
54
  };
48
55
  export type DocumentDataplyQuery<T> = {
49
56
  [key in keyof T]?: T[key] | DocumentDataplyCondition<T[key]>;
50
57
  } & {
51
58
  [key: string]: any;
52
59
  };
60
+ /**
61
+ * Query type restricted to indexed fields only (+ _id)
62
+ */
63
+ export type IndexedDocumentDataplyQuery<T, I extends string> = {
64
+ [key in (I | '_id')]?: key extends keyof T ? T[key] | DocumentDataplyCondition<T[key]> : never;
65
+ };
53
66
  export interface DataplyTreeValue<T> {
54
67
  k: number;
55
68
  v: T;
@@ -64,8 +77,8 @@ type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
64
77
  */
65
78
  export type DeepFlattenKeys<T, Prefix extends string = "", D extends number = 12> = [
66
79
  D
67
- ] extends [0] ? never : T extends Primitive ? (Prefix extends `${infer P}.` ? P : never) : T extends readonly any[] ? ((Prefix extends `${infer P}.` ? P : never) | DeepFlattenKeys<T[number], `${Prefix}${number}.`, Prev[D]>) : T extends object ? {
68
- [K in keyof T & string]: NonNullable<T[K]> extends Primitive ? `${Prefix}${K}` : `${Prefix}${K}` | DeepFlattenKeys<NonNullable<T[K]>, `${Prefix}${K}.`, Prev[D]>;
80
+ ] extends [0] ? never : T extends Primitive ? (Prefix extends `${infer P}.` ? P : never) : T extends readonly any[] ? (DeepFlattenKeys<T[number], `${Prefix}${number}.`, Prev[D]>) : T extends object ? {
81
+ [K in keyof T & string]: NonNullable<T[K]> extends Primitive ? `${Prefix}${K}` : DeepFlattenKeys<NonNullable<T[K]>, `${Prefix}${K}.`, Prev[D]>;
69
82
  }[keyof T & string] : never;
70
83
  /**
71
84
  * 경로 문자열(Path)을 기반으로 원본 객체(T)에서 타입을 찾아옵니다.
@@ -75,6 +88,15 @@ type GetTypeByPath<T, Path extends string> = T extends readonly (infer U)[] ? Pa
75
88
  export type FinalFlatten<T> = {
76
89
  [P in DeepFlattenKeys<T>]: GetTypeByPath<T, P & string>;
77
90
  };
78
- export interface DocumentDataplyOptions extends DataplyOptions {
91
+ export interface DocumentDataplyOptions<T> extends DataplyOptions {
92
+ /**
93
+ * Indecies to create when initializing the database.
94
+ * If not specified, no indecies will be created.
95
+ * If the value of the index is `true`, the index will be created for the already inserted data.
96
+ * If the value of the index is `false`, the index will not be created for the already inserted data.
97
+ */
98
+ indices?: Partial<{
99
+ [key in keyof FinalFlatten<T>]: boolean;
100
+ }>;
79
101
  }
80
102
  export {};
@@ -0,0 +1,12 @@
1
+ type CatchPromiseSuccess<T> = [undefined, T];
2
+ type CatchPromiseError = [Error];
3
+ type CatchPromiseResult<T> = CatchPromiseSuccess<T> | CatchPromiseError;
4
+ /**
5
+ * Catches a promise and returns a tuple of [error, result]
6
+ * If the promise is resolved, the first element of the tuple is `undefined`
7
+ * If the promise is rejected, the first element of the tuple is the `error`
8
+ * @param promise Promise to catch
9
+ * @returns Tuple of [error, result]
10
+ */
11
+ export declare function catchPromise<T>(promise: Promise<T>): Promise<CatchPromiseResult<T>>;
12
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "document-dataply",
3
- "version": "0.0.2-alpha.2",
4
- "description": "",
3
+ "version": "0.0.2",
4
+ "description": "Simple and powerful JSON document database supporting complex queries and flexible indexing policies.",
5
5
  "license": "MIT",
6
6
  "author": "izure <admin@izure.org>",
7
7
  "type": "commonjs",
@@ -25,8 +25,21 @@
25
25
  "test": "jest -i",
26
26
  "build": "node build/index.js && tsc"
27
27
  },
28
+ "keywords": [
29
+ "database",
30
+ "document-database",
31
+ "nosql",
32
+ "json",
33
+ "indexing",
34
+ "bptree",
35
+ "transactions",
36
+ "acid",
37
+ "embedded-database",
38
+ "deep-indexing",
39
+ "dataply"
40
+ ],
28
41
  "dependencies": {
29
- "dataply": "^0.0.16-alpha.0"
42
+ "dataply": "^0.0.18"
30
43
  },
31
44
  "devDependencies": {
32
45
  "@types/jest": "^30.0.0",