@aiao/rxdb-adapter-pglite 0.0.1

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.
@@ -0,0 +1,71 @@
1
+ import { DescribeQueryResult, QueryOptions, Results, Transaction } from '@electric-sql/pglite';
2
+ interface PGliteClientOptions {
3
+ store?: 'memory' | 'idb';
4
+ }
5
+ export interface IPGliteClient {
6
+ init(dbName: string, options: PGliteClientOptions): Promise<void>;
7
+ /**
8
+ * 执行单个 SQL 语句
9
+ * 使用 PostgreSQL 的"扩展查询"协议消息
10
+ * @param query 要执行的查询语句
11
+ * @param params 查询的可选参数
12
+ * @returns 查询的结果
13
+ */
14
+ query<T>(query: string, params?: any[], options?: QueryOptions): Promise<Results<T>>;
15
+ /**
16
+ * 执行单个 SQL 语句,类似于 query,但使用模板语句,其中模板值将被视为参数
17
+ *
18
+ * 使用 PostgreSQL 的"扩展查询"协议消息
19
+ *
20
+ * @param query 要执行的查询,参数作为模板值
21
+ * @returns 查询的结果
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const results = await db.sql`SELECT * FROM ${identifier`foo`} WHERE id = ${id}`
26
+ * ```
27
+ */
28
+ sql<T>(sqlStrings: TemplateStringsArray, ...params: any[]): Promise<Results<T>>;
29
+ /**
30
+ * 执行 SQL 查询,可以包含多个语句
31
+ * 使用 PostgreSQL 的"简单查询"协议消息
32
+ * @param query 要执行的查询
33
+ * @returns 查询的结果
34
+ */
35
+ exec(query: string, options?: QueryOptions): Promise<Array<Results>>;
36
+ /**
37
+ * 描述查询
38
+ * @param query 要描述的查询
39
+ * @returns 查询结果类型的描述
40
+ */
41
+ describeQuery(query: string, options?: QueryOptions): Promise<DescribeQueryResult>;
42
+ /**
43
+ * 执行事务
44
+ * @param callback 接收事务对象的回调函数
45
+ * @returns 事务的结果
46
+ */
47
+ transaction<T>(callback: (tx: Transaction) => Promise<T>): Promise<T>;
48
+ /**
49
+ * 独占运行函数,在函数运行期间不允许其他事务或查询
50
+ * 这在使用 execProtocol 方法时特别有用,因为它们不会被阻塞,
51
+ * 也不会阻塞事务和查询使用的锁
52
+ * @param fn 要运行的函数
53
+ * @returns 函数的结果
54
+ */
55
+ runExclusive<T>(fn: () => Promise<T>): Promise<T>;
56
+ disconnect(): Promise<void>;
57
+ version(): Promise<string>;
58
+ }
59
+ export declare class PGliteClient implements IPGliteClient {
60
+ #private;
61
+ init(dbName: string, options: PGliteClientOptions): Promise<void>;
62
+ sql<T>(sqlStrings: TemplateStringsArray, ...params: any[]): Promise<Results<T>>;
63
+ exec(query: string, options?: QueryOptions): Promise<Array<Results>>;
64
+ query<T>(query: string, params?: any[], options?: QueryOptions): Promise<Results<T>>;
65
+ describeQuery(query: string, options?: QueryOptions): Promise<DescribeQueryResult>;
66
+ transaction<T>(callback: (tx: Transaction) => Promise<T>): Promise<T>;
67
+ runExclusive<T>(fn: () => Promise<T>): Promise<T>;
68
+ disconnect(): Promise<void>;
69
+ version(): Promise<string>;
70
+ }
71
+ export {};
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # rxdb-adapter-pglite
@@ -0,0 +1,33 @@
1
+ import { EntityType, IRepository, IRxDBAdapter, RxDB, RxDBAdapterLocalBase, TransactionFun } from '@aiao/rxdb';
2
+ import { Observable } from 'rxjs';
3
+ import { ADAPTER_NAME, PGliteOptions } from './pglite.interface';
4
+ export declare class RxDBAdapterPGlite extends RxDBAdapterLocalBase implements IRxDBAdapter {
5
+ #private;
6
+ private readonly options;
7
+ /**
8
+ * 数据库版本
9
+ */
10
+ version$: Observable<string>;
11
+ name: string;
12
+ constructor(rxdb: RxDB, options: PGliteOptions);
13
+ connect(): Observable<this>;
14
+ disconnect(): Promise<void>;
15
+ /**
16
+ * 获取版本
17
+ */
18
+ version(): Promise<string>;
19
+ getRepository<T extends EntityType, RT extends IRepository<T>>(EntityType: EntityType): RT;
20
+ createTable(EntityType: EntityType): Promise<boolean>;
21
+ isTableExisted(EntityType: EntityType): Promise<boolean>;
22
+ /**
23
+ * 判断表是否存在
24
+ * @param EntityType
25
+ */
26
+ isTableExisted$<T extends EntityType>(EntityType: T): Observable<boolean>;
27
+ transaction(fun: TransactionFun): Promise<any>;
28
+ }
29
+ declare module '@aiao/rxdb' {
30
+ interface RxDBAdapters {
31
+ [ADAPTER_NAME]: RxDBAdapterPGlite;
32
+ }
33
+ }
@@ -0,0 +1,4 @@
1
+ import { EntityMetadata } from '@aiao/rxdb';
2
+ import { RxDBAdapterPGlite } from './RxDBAdapterPGlite';
3
+ declare const _default: (adapter: RxDBAdapterPGlite, metadata: EntityMetadata) => string;
4
+ export default _default;
package/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { RxdbAdapterPGliteError } from './pglite.utils';
2
+ export * from './RxDBAdapterPGlite';
package/index.js ADDED
@@ -0,0 +1,170 @@
1
+ import { RxDBError as _, PropertyType as i, TransactionBeginEvent as b, TransactionCommitEvent as f, TransactionRollbackEvent as w, RxDBAdapterLocalBase as x, getEntityMetadata as E } from "@aiao/rxdb";
2
+ import { Observable as $, shareReplay as T, switchMap as l, from as g, map as u, firstValueFrom as m } from "rxjs";
3
+ import { isFunction as y, isString as R } from "@aiao/utils";
4
+ import { PGlite as q } from "@electric-sql/pglite";
5
+ class v extends _ {
6
+ }
7
+ const A = (s) => {
8
+ switch (s.type) {
9
+ case i.uuid:
10
+ return "uuid";
11
+ case i.string:
12
+ return "varchar";
13
+ case i.json:
14
+ return "jsonb";
15
+ case i.number:
16
+ return "numeric";
17
+ case i.integer:
18
+ return "integer";
19
+ case i.boolean:
20
+ return "boolean";
21
+ case i.date:
22
+ return "timestamptz";
23
+ }
24
+ }, L = (s) => {
25
+ switch (s.type) {
26
+ case i.uuid:
27
+ return "uuid_ops";
28
+ case i.string:
29
+ return "bpchar_ops";
30
+ case i.json:
31
+ return "jsonb_ops";
32
+ case i.number:
33
+ return "numeric_ops";
34
+ case i.integer:
35
+ return "int4_ops";
36
+ default:
37
+ throw new Error(`rxDBColumnTypeToPGliteTypeIndexName: type '${s.type}' not support`);
38
+ }
39
+ }, C = (s, e) => `idx_${s.namespace}_${s.name}_${e.name}`, D = (s, e) => {
40
+ let t = `CREATE TABLE ${e.namespace}."${e.name}" (`;
41
+ const r = [], c = [], p = [];
42
+ e.propertyMap.forEach((n) => {
43
+ let o = "";
44
+ o += `"${n.name}"`;
45
+ const d = A(n);
46
+ if (n.primary ? n.type === i.integer ? o += " serial PRIMARY KEY" : o += ` ${d} PRIMARY KEY` : o += ` ${d}`, !n.nullable) o += " NOT NULL";
47
+ else if (Reflect.get(n, "default") !== void 0) {
48
+ let a = n.default;
49
+ y(n.default) && (a = n.default()), R(a) ? ["CURRENT_TIMESTAMP", "now()"].includes(a) ? o += " DEFAULT now()" : o += ` DEFAULT '${a}'` : o += ` DEFAULT ${String(a)}`;
50
+ }
51
+ n.unique && r.push(
52
+ `CREATE UNIQUE INDEX "${C(e, n)}" on ${e.namespace}."${e.name}" ("${n.name}" ${L(n)});`
53
+ ), p.push(o);
54
+ });
55
+ const h = [...p, ...c];
56
+ if (h.length)
57
+ t += h.map((n) => `
58
+ ${n}`).join(","), t += `
59
+ );`;
60
+ else
61
+ throw new v("columns is empty!");
62
+ return r.length && (t += `
63
+ ` + r.join(`
64
+ `)), t;
65
+ }, M = (s, e) => "", P = (s, e) => {
66
+ let t = "";
67
+ return t += D(s, e), t += M(), t;
68
+ }, S = "pglite";
69
+ class N {
70
+ #e;
71
+ async init(e, t) {
72
+ return this.#e = new q({
73
+ dataDir: t.store === "memory" ? void 0 : `idb://${e}`,
74
+ database: e
75
+ }), this.#e.waitReady;
76
+ }
77
+ sql(e, ...t) {
78
+ return this.#e.sql(e, ...t);
79
+ }
80
+ exec(e, t) {
81
+ return this.#e.exec(e, t);
82
+ }
83
+ query(e, t, r) {
84
+ return this.#e.query(e, t, r);
85
+ }
86
+ describeQuery(e, t) {
87
+ return this.#e.describeQuery(e, t);
88
+ }
89
+ transaction(e) {
90
+ return this.#e.transaction(e);
91
+ }
92
+ runExclusive(e) {
93
+ return this.#e.runExclusive(e);
94
+ }
95
+ disconnect() {
96
+ throw new Error("Method not implemented.");
97
+ }
98
+ async version() {
99
+ return (await this.#e.query("SELECT version()")).rows[0].version;
100
+ }
101
+ }
102
+ class U extends x {
103
+ constructor(e, t) {
104
+ super(e), this.options = t;
105
+ }
106
+ #e = new $((e) => {
107
+ const t = new N();
108
+ t.init(this.rxdb.options.dbName, this.options).then(() => e.next(t));
109
+ }).pipe(T(1));
110
+ /**
111
+ * 数据库版本
112
+ */
113
+ version$ = this.#e.pipe(
114
+ l((e) => g(e.version())),
115
+ T(1)
116
+ );
117
+ name = S;
118
+ connect() {
119
+ return this.#e.pipe(u(() => this));
120
+ }
121
+ disconnect() {
122
+ throw new Error("Method disconnect not implemented.");
123
+ }
124
+ /**
125
+ * 获取版本
126
+ */
127
+ version() {
128
+ return m(this.version$);
129
+ }
130
+ getRepository(e) {
131
+ throw new Error("Method getRepository not implemented.");
132
+ }
133
+ createTable(e) {
134
+ const t = E(e), r = P(this, t);
135
+ return t.log, m(this.#n(r).pipe(u(() => !0)));
136
+ }
137
+ async isTableExisted(e) {
138
+ return m(this.isTableExisted$(e));
139
+ }
140
+ /**
141
+ * 判断表是否存在
142
+ * @param EntityType
143
+ */
144
+ isTableExisted$(e) {
145
+ const t = E(e);
146
+ return this.#t(
147
+ `SELECT EXISTS (
148
+ SELECT 1
149
+ FROM information_schema.tables
150
+ WHERE table_schema = '${t.namespace}'
151
+ AND table_name = '${t.name}');`
152
+ ).pipe(u((r) => r.rows[0]?.exists));
153
+ }
154
+ transaction(e) {
155
+ throw new Error("Method transaction not implemented.");
156
+ }
157
+ #t(e, t, r) {
158
+ return this.#e.pipe(l((c) => c.query(e, t, r)));
159
+ }
160
+ #n(e, t) {
161
+ return this.#e.pipe(l((r) => r.exec(e, t)));
162
+ }
163
+ }
164
+ new b();
165
+ new f();
166
+ new w();
167
+ export {
168
+ U as RxDBAdapterPGlite,
169
+ v as RxdbAdapterPGliteError
170
+ };
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@aiao/rxdb-adapter-pglite",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "main": "./index.js",
6
+ "types": "./index.d.ts",
7
+ "dependencies": {
8
+ "@electric-sql/pglite": "^0.3.6",
9
+ "@aiao/rxdb": "0.0.1",
10
+ "rxjs": "~7.8.2",
11
+ "@aiao/utils": "0.0.1"
12
+ },
13
+ "publishConfig": {
14
+ "access": "public"
15
+ }
16
+ }
@@ -0,0 +1,5 @@
1
+ import { IRxDBAdapterOptions } from '@aiao/rxdb';
2
+ export declare const ADAPTER_NAME: "pglite";
3
+ export interface PGliteOptions extends IRxDBAdapterOptions {
4
+ store?: 'memory' | 'idb';
5
+ }
@@ -0,0 +1,16 @@
1
+ import { EntityMetadata, EntityPropertyMetadata, EntityRelationMetadata, RxDBError } from '@aiao/rxdb';
2
+ export declare class RxdbAdapterPGliteError extends RxDBError {
3
+ }
4
+ export declare const getTableNameByMetadata: (metadata: EntityMetadata) => string;
5
+ type PGliteDataType = 'uuid' | 'varchar' | 'jsonb' | 'numeric' | 'integer' | 'boolean' | 'timestamptz';
6
+ /**
7
+ * rxdb 的类型 转 PGlite 类型
8
+ */
9
+ export declare const rxDBColumnTypeToPGliteType: (property: EntityPropertyMetadata) => PGliteDataType;
10
+ /**
11
+ * 获取属性的 index 操作符
12
+ *http://www.postgres.cn/docs/current/indexes-opclass.html
13
+ */
14
+ export declare const rxDBColumnTypeToPGliteTypeIndexName: (property: EntityPropertyMetadata) => string;
15
+ export declare const getTableColumnIndexName: (metadata: EntityMetadata, property: EntityPropertyMetadata | EntityRelationMetadata) => string;
16
+ export {};