core-3nweb-client-lib 0.28.4 → 0.29.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,6 @@
1
+ export interface Deferred<T> {
2
+ promise: Promise<T>;
3
+ resolve: (result?: T | PromiseLike<T>) => void;
4
+ reject: (err: any) => void;
5
+ }
6
+ export declare function defer<T>(): Deferred<T>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2015, 2017, 2019 - 2022 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.defer = void 0;
20
+ function defer() {
21
+ const d = {};
22
+ d.promise = new Promise((resolve, reject) => {
23
+ d.resolve = resolve;
24
+ d.reject = reject;
25
+ });
26
+ Object.freeze(d);
27
+ return d;
28
+ }
29
+ exports.defer = defer;
@@ -1,32 +1,49 @@
1
- import { Action, SingleProc } from '../lib-common/processes/synced';
2
- import { Database as DBClass, BindParams as QueryParams, QueryExecResult as QueryResult } from './sqljs';
1
+ import { Database as DBClass, BindParams as QueryParams, QueryExecResult as QueryResult } from './sqljs.js';
2
+ import { SingleProc, Action } from './synced.js';
3
3
  export declare type Database = DBClass;
4
4
  export declare type BindParams = QueryParams;
5
5
  export declare type QueryExecResult = QueryResult;
6
6
  declare type WritableFile = web3n.files.WritableFile;
7
- declare type ReadonlyFile = web3n.files.ReadonlyFile;
7
+ export interface SaveOpts {
8
+ skipUpload?: boolean;
9
+ }
8
10
  export declare abstract class SQLiteOn3NStorage {
9
11
  protected readonly database: Database;
10
12
  protected readonly file: WritableFile;
11
13
  protected readonly syncProc: SingleProc;
12
14
  protected constructor(database: Database, file: WritableFile);
15
+ static makeAndStart(file: WritableFile): Promise<SQLiteOn3NStorage>;
16
+ private start;
17
+ saveToFile(opts?: SaveOpts): Promise<void>;
13
18
  get db(): Database;
14
- get dbFile(): WritableFile;
15
19
  sync<T>(action: Action<T>): Promise<T>;
16
20
  listTables(): string[];
17
21
  }
18
- export declare class SQLiteOnUnversionedFS extends SQLiteOn3NStorage {
19
- static makeAndStart(file: WritableFile): Promise<SQLiteOnUnversionedFS>;
20
- saveToFile(): Promise<void>;
21
- }
22
- export declare class SQLiteOnVersionedFS extends SQLiteOn3NStorage {
23
- protected constructor(db: Database, file: WritableFile);
24
- static makeAndStart(file: WritableFile): Promise<SQLiteOnVersionedFS>;
25
- saveToFile(): Promise<number>;
26
- }
27
- export declare class SQLiteOnSyncedFS extends SQLiteOnVersionedFS {
28
- protected constructor(db: Database, file: WritableFile);
29
- static makeAndStart(file: WritableFile): Promise<SQLiteOnSyncedFS>;
22
+ export declare function objectFromQueryExecResult<T>(sqlResult: QueryExecResult): Array<T>;
23
+ declare type KeyedInfo<T> = {
24
+ [columnName in keyof T]: string;
25
+ };
26
+ export declare class TableColumnsAndParams<EntryType extends object> {
27
+ readonly name: string;
28
+ private readonly columnDefs;
29
+ readonly c: KeyedInfo<EntryType>;
30
+ readonly cReversed: {
31
+ [colName: string]: keyof EntryType;
32
+ };
33
+ readonly p: KeyedInfo<EntryType>;
34
+ readonly q: KeyedInfo<EntryType>;
35
+ readonly columnsCreateSection: string;
36
+ constructor(name: string, columnDefs: {
37
+ [columnName in keyof EntryType]: [string, string];
38
+ });
39
+ private toC;
40
+ toParams<T extends {
41
+ [field in keyof EntryType]: any;
42
+ }>(value: Partial<T>, addNullsForMissingFields?: boolean): any;
43
+ fromQueryExecResult<T>(sqlResult: QueryExecResult[]): Array<T>;
44
+ get insertQuery(): string;
45
+ updateQuery(withTabName: boolean, fields?: (keyof EntryType)[] | undefined, skipColumns?: boolean): string;
46
+ colsEqualSection(...fields: (keyof EntryType)[]): string;
47
+ colsSection(...fields: (keyof EntryType)[]): string;
30
48
  }
31
- export declare function readDbFrom(file: ReadonlyFile): Promise<Database>;
32
49
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2022 3NSoft Inc.
3
+ Copyright (C) 2022 - 2023 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -16,21 +16,45 @@
16
16
  this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.readDbFrom = exports.SQLiteOnSyncedFS = exports.SQLiteOnVersionedFS = exports.SQLiteOnUnversionedFS = exports.SQLiteOn3NStorage = void 0;
20
- const synced_1 = require("../lib-common/processes/synced");
21
- const sqljs_1 = require("./sqljs");
19
+ exports.TableColumnsAndParams = exports.objectFromQueryExecResult = exports.SQLiteOn3NStorage = void 0;
20
+ const sqljs_js_1 = require("./sqljs.js");
21
+ const synced_js_1 = require("./synced.js");
22
22
  class SQLiteOn3NStorage {
23
23
  constructor(database, file) {
24
24
  this.database = database;
25
25
  this.file = file;
26
- this.syncProc = new synced_1.SingleProc();
26
+ this.syncProc = new synced_js_1.SingleProc();
27
+ }
28
+ static async makeAndStart(file) {
29
+ var _a;
30
+ const SQL = await (0, sqljs_js_1.default)(true);
31
+ const fileContent = await readFileContent(file);
32
+ const db = new SQL.Database(fileContent);
33
+ let sqlite;
34
+ if ((_a = file.v) === null || _a === void 0 ? void 0 : _a.sync) {
35
+ sqlite = new SQLiteOnSyncedFS(db, file);
36
+ }
37
+ else if (file.v) {
38
+ sqlite = new SQLiteOnLocalFS(db, file);
39
+ }
40
+ else {
41
+ sqlite = new SQLiteOnDeviceFS(db, file);
42
+ }
43
+ await sqlite.start();
44
+ return sqlite;
45
+ }
46
+ async start() {
47
+ // XXX add listening process(es)
48
+ }
49
+ async saveToFile(opts) {
50
+ await this.syncProc.startOrChain(async () => {
51
+ const dbFileContent = this.database.export();
52
+ await this.file.writeBytes(dbFileContent);
53
+ });
27
54
  }
28
55
  get db() {
29
56
  return this.database;
30
57
  }
31
- get dbFile() {
32
- return this.file;
33
- }
34
58
  sync(action) {
35
59
  return this.syncProc.startOrChain(action);
36
60
  }
@@ -44,64 +68,39 @@ class SQLiteOn3NStorage {
44
68
  exports.SQLiteOn3NStorage = SQLiteOn3NStorage;
45
69
  Object.freeze(SQLiteOn3NStorage.prototype);
46
70
  Object.freeze(SQLiteOn3NStorage);
47
- class SQLiteOnUnversionedFS extends SQLiteOn3NStorage {
48
- static async makeAndStart(file) {
49
- const db = await readDbFrom(file);
50
- return new SQLiteOnUnversionedFS(db, file);
71
+ class SQLiteOnSyncedFS extends SQLiteOn3NStorage {
72
+ constructor(db, file) {
73
+ super(db, file);
74
+ Object.seal(this);
51
75
  }
52
- async saveToFile() {
53
- await this.syncProc.startOrChain(async () => {
54
- const dbFileContent = this.database.export();
55
- await this.file.writeBytes(dbFileContent);
56
- });
76
+ async saveToFile(opts) {
77
+ await super.saveToFile();
78
+ if (opts === null || opts === void 0 ? void 0 : opts.skipUpload) {
79
+ return;
80
+ }
81
+ else {
82
+ await this.file.v.sync.upload();
83
+ }
57
84
  }
58
85
  }
59
- exports.SQLiteOnUnversionedFS = SQLiteOnUnversionedFS;
60
- Object.freeze(SQLiteOnUnversionedFS.prototype);
61
- Object.freeze(SQLiteOnUnversionedFS);
62
- class SQLiteOnVersionedFS extends SQLiteOn3NStorage {
86
+ Object.freeze(SQLiteOnSyncedFS.prototype);
87
+ Object.freeze(SQLiteOnSyncedFS);
88
+ class SQLiteOnLocalFS extends SQLiteOn3NStorage {
63
89
  constructor(db, file) {
64
90
  super(db, file);
65
- if (!file.v) {
66
- throw new Error(`Given file is not versioned`);
67
- }
68
- }
69
- static async makeAndStart(file) {
70
- const db = await readDbFrom(file);
71
- return new SQLiteOnVersionedFS(db, file);
72
- }
73
- async saveToFile() {
74
- return await this.syncProc.startOrChain(async () => {
75
- const dbFileContent = this.database.export();
76
- return await this.file.v.writeBytes(dbFileContent);
77
- });
91
+ Object.seal(this);
78
92
  }
79
93
  }
80
- exports.SQLiteOnVersionedFS = SQLiteOnVersionedFS;
81
- Object.freeze(SQLiteOnVersionedFS.prototype);
82
- Object.freeze(SQLiteOnVersionedFS);
83
- class SQLiteOnSyncedFS extends SQLiteOnVersionedFS {
94
+ Object.freeze(SQLiteOnLocalFS.prototype);
95
+ Object.freeze(SQLiteOnLocalFS);
96
+ class SQLiteOnDeviceFS extends SQLiteOn3NStorage {
84
97
  constructor(db, file) {
85
- var _a;
86
98
  super(db, file);
87
- if (!((_a = file.v) === null || _a === void 0 ? void 0 : _a.sync)) {
88
- throw new Error(`Given file is not synced`);
89
- }
90
- }
91
- static async makeAndStart(file) {
92
- const db = await readDbFrom(file);
93
- return new SQLiteOnSyncedFS(db, file);
99
+ Object.seal(this);
94
100
  }
95
101
  }
96
- exports.SQLiteOnSyncedFS = SQLiteOnSyncedFS;
97
- Object.freeze(SQLiteOnSyncedFS.prototype);
98
- Object.freeze(SQLiteOnSyncedFS);
99
- async function readDbFrom(file) {
100
- const SQL = await (0, sqljs_1.default)(true);
101
- const fileContent = await readFileContent(file);
102
- return new SQL.Database(fileContent);
103
- }
104
- exports.readDbFrom = readDbFrom;
102
+ Object.freeze(SQLiteOnDeviceFS.prototype);
103
+ Object.freeze(SQLiteOnDeviceFS);
105
104
  async function readFileContent(file) {
106
105
  try {
107
106
  return await file.readBytes();
@@ -115,3 +114,107 @@ async function readFileContent(file) {
115
114
  }
116
115
  }
117
116
  }
117
+ function objectFromQueryExecResult(sqlResult) {
118
+ const { columns, values: rows } = sqlResult;
119
+ return rows.map(row => row.reduce((obj, cellValue, index) => {
120
+ const field = columns[index];
121
+ obj[field] = cellValue;
122
+ return obj;
123
+ }, {}));
124
+ }
125
+ exports.objectFromQueryExecResult = objectFromQueryExecResult;
126
+ class TableColumnsAndParams {
127
+ constructor(name, columnDefs) {
128
+ this.name = name;
129
+ this.columnDefs = columnDefs;
130
+ this.columnsCreateSection = Object.values(columnDefs)
131
+ .map(([colName, colCreate]) => `${colName} ${colCreate}`)
132
+ .join(`,\n`);
133
+ this.c = {};
134
+ this.cReversed = {};
135
+ this.p = {};
136
+ this.q = {};
137
+ for (const [field, [colName]] of Object.entries(this.columnDefs)) {
138
+ this.c[field] = colName;
139
+ this.cReversed[colName] = field;
140
+ this.p[field] = `$${field}`;
141
+ this.q[field] = `${this.name}.${colName}`;
142
+ }
143
+ Object.freeze(this.c);
144
+ Object.freeze(this.p);
145
+ Object.freeze(this.q);
146
+ Object.freeze(this.name);
147
+ Object.freeze(this.columnsCreateSection);
148
+ }
149
+ toC(field) {
150
+ const colName = this.c[field];
151
+ if (colName === undefined) {
152
+ throw new Error(`Column for ${field} is not found among columns of table ${this.name}`);
153
+ }
154
+ return colName;
155
+ }
156
+ toParams(value, addNullsForMissingFields = false) {
157
+ const params = {};
158
+ for (const [field, columnValue] of Object.entries(value)) {
159
+ this.toC(field); // does implicit check for column existence
160
+ params[this.p[field]] = columnValue;
161
+ }
162
+ if (addNullsForMissingFields) {
163
+ for (const paramName of Object.values(this.p)) {
164
+ if (params[paramName] === undefined) {
165
+ params[paramName] = null;
166
+ }
167
+ }
168
+ }
169
+ return params;
170
+ }
171
+ fromQueryExecResult(sqlResult) {
172
+ if (sqlResult.length === 0) {
173
+ return [];
174
+ }
175
+ if (sqlResult.length > 1) {
176
+ throw new Error(`This method will not process result of many queries`);
177
+ }
178
+ const { columns, values: rows } = sqlResult[0];
179
+ return rows.map(row => row.reduce((obj, cellValue, index) => {
180
+ const tabColumn = columns[index];
181
+ let field = this.cReversed[tabColumn];
182
+ if (field === undefined) {
183
+ field = tabColumn;
184
+ }
185
+ obj[field] = cellValue;
186
+ return obj;
187
+ }, {}));
188
+ }
189
+ get insertQuery() {
190
+ const colAndParamNames = Object.entries(this.p);
191
+ return `INSERT INTO ${this.name} (${colAndParamNames.map(([field]) => this.toC(field)).join(', ')}) VALUES (${colAndParamNames.map(([n, colParam]) => colParam).join(', ')})`;
192
+ }
193
+ updateQuery(withTabName, fields = undefined, skipColumns = false) {
194
+ let fieldAndParamNames = Object.entries(this.p);
195
+ if (fields) {
196
+ if (skipColumns) {
197
+ fieldAndParamNames = fieldAndParamNames.filter(([field]) => !fields.includes(field));
198
+ }
199
+ else {
200
+ fieldAndParamNames = fieldAndParamNames.filter(([field]) => fields.includes(field));
201
+ }
202
+ }
203
+ return `UPDATE ${withTabName ? `${this.name} ` : ''}SET ${fieldAndParamNames
204
+ .map(([field, pName]) => `${this.toC(field)}=${pName}`)
205
+ .join(', ')}`;
206
+ }
207
+ colsEqualSection(...fields) {
208
+ return (fields)
209
+ .map(n => `${this.toC(n)}=${this.p[n]}`)
210
+ .join(' AND ');
211
+ }
212
+ colsSection(...fields) {
213
+ return (fields)
214
+ .map(n => this.toC(n))
215
+ .join(', ');
216
+ }
217
+ }
218
+ exports.TableColumnsAndParams = TableColumnsAndParams;
219
+ Object.freeze(TableColumnsAndParams.prototype);
220
+ Object.freeze(TableColumnsAndParams);