Skip to content

Commit c00b9e2

Browse files
committed
Reduce lodash usage.
1 parent 41dc251 commit c00b9e2

File tree

11 files changed

+73
-67
lines changed

11 files changed

+73
-67
lines changed

packages/powersync-sdk-common/src/client/AbstractPowerSyncDatabase.ts

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
import _ from 'lodash';
21
import { Mutex } from 'async-mutex';
2+
import { EventIterator } from 'event-iterator';
33
import Logger, { ILogger } from 'js-logger';
4+
import intersection from 'lodash/intersection';
5+
import throttle from 'lodash/throttle';
46
import { DBAdapter, QueryResult, Transaction, isBatchedUpdateNotification } from '../db/DBAdapter';
5-
import { Schema } from '../db/schema/Schema';
67
import { SyncStatus } from '../db/crud/SyncStatus';
78
import { UploadQueueStats } from '../db/crud/UploadQueueStatus';
9+
import { Schema } from '../db/schema/Schema';
10+
import { BaseObserver } from '../utils/BaseObserver';
11+
import { mutexRunExclusive } from '../utils/mutex';
12+
import { quoteIdentifier } from '../utils/strings';
813
import { PowerSyncBackendConnector } from './connection/PowerSyncBackendConnector';
14+
import { BucketStorageAdapter, PSInternalTable } from './sync/bucket/BucketStorageAdapter';
15+
import { CrudBatch } from './sync/bucket/CrudBatch';
16+
import { CrudEntry, CrudEntryJSON } from './sync/bucket/CrudEntry';
17+
import { CrudTransaction } from './sync/bucket/CrudTransaction';
918
import {
1019
AbstractStreamingSyncImplementation,
1120
DEFAULT_CRUD_UPLOAD_THROTTLE_MS,
1221
StreamingSyncImplementationListener
1322
} from './sync/stream/AbstractStreamingSyncImplementation';
14-
import { CrudBatch } from './sync/bucket/CrudBatch';
15-
import { CrudTransaction } from './sync/bucket/CrudTransaction';
16-
import { BucketStorageAdapter, PSInternalTable } from './sync/bucket/BucketStorageAdapter';
17-
import { CrudEntry, CrudEntryJSON } from './sync/bucket/CrudEntry';
18-
import { mutexRunExclusive } from '../utils/mutex';
19-
import { BaseObserver } from '../utils/BaseObserver';
20-
import { EventIterator } from 'event-iterator';
21-
import { quoteIdentifier } from '../utils/strings';
2223

2324
export interface DisconnectAndClearOptions {
2425
/** When set to false, data in local-only tables is preserved. */
@@ -538,25 +539,26 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
538539
* Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
539540
*/
540541
async *watch(sql: string, parameters?: any[], options?: SQLWatchOptions): AsyncIterable<QueryResult> {
541-
//Fetch initial data
542+
// Fetch initial data
542543
yield await this.executeReadOnly(sql, parameters);
543544

544-
const resolvedTables = options?.tables ?? [];
545+
const resolvedTables = options?.tables ? [...options.tables] : [];
545546
if (!options?.tables) {
546547
const explained = await this.getAll<{ opcode: string; p3: number; p2: number }>(`EXPLAIN ${sql}`, parameters);
547-
const rootPages = _.chain(explained)
548-
.filter((row) => row['opcode'] == 'OpenRead' && row['p3'] == 0 && _.isNumber(row['p2']))
549-
.map((row) => row['p2'])
550-
.value();
548+
const rootPages = explained
549+
.filter((row) => row.opcode == 'OpenRead' && row.p3 == 0 && typeof row.p2 == 'number')
550+
.map((row) => row.p2);
551551
const tables = await this.getAll<{ tbl_name: string }>(
552-
`SELECT tbl_name FROM sqlite_master WHERE rootpage IN (SELECT json_each.value FROM json_each(?))`,
552+
`SELECT DISTINCT tbl_name FROM sqlite_master WHERE rootpage IN (SELECT json_each.value FROM json_each(?))`,
553553
[JSON.stringify(rootPages)]
554554
);
555-
tables.forEach((t) => resolvedTables.push(t.tbl_name.replace(POWERSYNC_TABLE_MATCH, '')));
555+
for (let table of tables) {
556+
resolvedTables.push(table.tbl_name.replace(POWERSYNC_TABLE_MATCH, ''));
557+
}
556558
}
557559
for await (const event of this.onChange({
558560
...(options ?? {}),
559-
tables: _.uniq(resolvedTables)
561+
tables: resolvedTables
560562
})) {
561563
yield await this.executeReadOnly(sql, parameters);
562564
}
@@ -578,12 +580,12 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
578580
const throttleMs = resolvedOptions.throttleMs ?? DEFAULT_WATCH_THROTTLE_MS;
579581

580582
return new EventIterator<WatchOnChangeEvent>((eventOptions) => {
581-
const flushTableUpdates = _.throttle(
583+
const flushTableUpdates = throttle(
582584
() => {
583-
const intersection = _.intersection(watchedTables, throttledTableUpdates);
584-
if (intersection.length) {
585+
const changedTables = intersection(watchedTables, throttledTableUpdates);
586+
if (changedTables.length > 0) {
585587
eventOptions.push({
586-
changedTables: intersection
588+
changedTables
587589
});
588590
}
589591
throttledTableUpdates = [];

packages/powersync-sdk-common/src/client/sync/bucket/CrudEntry.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import _ from 'lodash';
1+
import isEqual from 'lodash/isEqual';
22

33
/**
44
* 64-bit unsigned integer stored as a string in base-10.
@@ -109,7 +109,7 @@ export class CrudEntry {
109109
}
110110

111111
equals(entry: CrudEntry) {
112-
return _.isEqual(this.toComparisonArray(), entry.toComparisonArray());
112+
return isEqual(this.toComparisonArray(), entry.toComparisonArray());
113113
}
114114

115115
/**

packages/powersync-sdk-common/src/client/sync/stream/AbstractStreamingSyncImplementation.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import _ from 'lodash';
1+
import throttle from 'lodash/throttle';
2+
import defer from 'lodash/defer';
3+
24
import Logger, { ILogger } from 'js-logger';
35

46
import {
@@ -76,7 +78,7 @@ export abstract class AbstractStreamingSyncImplementation extends BaseObserver<S
7678
}
7779
});
7880

79-
this.triggerCrudUpload = _.throttle(
81+
this.triggerCrudUpload = throttle(
8082
() => {
8183
if (!this.syncStatus.connected || this.syncStatus.dataFlowStatus.uploading) {
8284
return;
@@ -206,6 +208,7 @@ export abstract class AbstractStreamingSyncImplementation extends BaseObserver<S
206208
after: after
207209
}));
208210

211+
// These are compared by reference
209212
let targetCheckpoint: Checkpoint | null = null;
210213
let validatedCheckpoint: Checkpoint | null = null;
211214
let appliedCheckpoint: Checkpoint | null = null;
@@ -223,7 +226,7 @@ export abstract class AbstractStreamingSyncImplementation extends BaseObserver<S
223226
// A connection is active and messages are being received
224227
if (!this.syncStatus.connected) {
225228
// There is a connection now
226-
_.defer(() => this.triggerCrudUpload());
229+
defer(() => this.triggerCrudUpload());
227230
this.updateSyncStatus({
228231
connected: true
229232
});
@@ -256,7 +259,7 @@ export abstract class AbstractStreamingSyncImplementation extends BaseObserver<S
256259
// Continue waiting.
257260
// landing here the whole time
258261
} else {
259-
appliedCheckpoint = _.clone(targetCheckpoint);
262+
appliedCheckpoint = targetCheckpoint;
260263
this.logger.debug('validated checkpoint', appliedCheckpoint);
261264
this.updateSyncStatus({
262265
connected: true,
@@ -267,7 +270,7 @@ export abstract class AbstractStreamingSyncImplementation extends BaseObserver<S
267270
});
268271
}
269272

270-
validatedCheckpoint = _.clone(targetCheckpoint);
273+
validatedCheckpoint = targetCheckpoint;
271274
} else if (isStreamingSyncCheckpointDiff(line)) {
272275
// TODO: It may be faster to just keep track of the diff, instead of the entire checkpoint
273276
if (targetCheckpoint == null) {
@@ -319,12 +322,12 @@ export abstract class AbstractStreamingSyncImplementation extends BaseObserver<S
319322
} else {
320323
this.logger.debug('Sync complete');
321324

322-
if (_.isEqual(targetCheckpoint, appliedCheckpoint)) {
325+
if (targetCheckpoint === appliedCheckpoint) {
323326
this.updateSyncStatus({
324327
connected: true,
325328
lastSyncedAt: new Date()
326329
});
327-
} else if (_.isEqual(validatedCheckpoint, targetCheckpoint)) {
330+
} else if (validatedCheckpoint === targetCheckpoint) {
328331
const result = await this.options.adapter.syncLocalDatabase(targetCheckpoint!);
329332
if (!result.checkpointValid) {
330333
// This means checksums failed. Start again with a new checkpoint.
@@ -335,7 +338,7 @@ export abstract class AbstractStreamingSyncImplementation extends BaseObserver<S
335338
// Checksums valid, but need more data for a consistent checkpoint.
336339
// Continue waiting.
337340
} else {
338-
appliedCheckpoint = _.clone(targetCheckpoint);
341+
appliedCheckpoint = targetCheckpoint;
339342
this.updateSyncStatus({
340343
connected: true,
341344
lastSyncedAt: new Date(),
@@ -378,7 +381,10 @@ export abstract class AbstractStreamingSyncImplementation extends BaseObserver<S
378381
const updatedStatus = new SyncStatus({
379382
connected: options.connected ?? this.syncStatus.connected,
380383
lastSyncedAt: options.lastSyncedAt ?? this.syncStatus.lastSyncedAt,
381-
dataFlow: _.merge(_.clone(this.syncStatus.dataFlowStatus), options.dataFlow ?? {})
384+
dataFlow: {
385+
...this.syncStatus.dataFlowStatus,
386+
...options.dataFlow
387+
}
382388
});
383389

384390
if (!this.syncStatus.isEqual(updatedStatus)) {

packages/powersync-sdk-common/src/db/crud/SyncStatus.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import _ from 'lodash';
1+
import isEqual from 'lodash/isEqual';
22

33
export type SyncDataFlowStatus = Partial<{
44
downloading: boolean;
@@ -49,7 +49,7 @@ export class SyncStatus {
4949
}
5050

5151
isEqual(status: SyncStatus) {
52-
return _.isEqual(this.options, status.options);
52+
return isEqual(this.options, status.options);
5353
}
5454

5555
getMessage() {

packages/powersync-sdk-common/src/db/schema/Table.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import _, { indexOf } from 'lodash';
21
import { Column } from '../Column';
32
import type { Index } from './Index';
43
import { TableV2 } from './TableV2';
@@ -86,10 +85,13 @@ export class Table {
8685
}
8786

8887
get validName() {
89-
return _.chain([this.name, this.viewNameOverride])
90-
.compact()
91-
.every((name) => !InvalidSQLCharacters.test(name))
92-
.value();
88+
if (InvalidSQLCharacters.test(this.name)) {
89+
return false;
90+
}
91+
if (this.viewNameOverride != null && InvalidSQLCharacters.test(this.viewNameOverride)) {
92+
return false;
93+
}
94+
return true;
9395
}
9496

9597
validate() {

packages/powersync-sdk-web/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import _ from 'lodash';
21
import {
32
AbstractPowerSyncDatabase,
43
AbstractPowerSyncDatabaseOpenFactory,
@@ -73,10 +72,14 @@ export abstract class AbstractWebPowerSyncDatabaseOpenFactory extends AbstractPo
7372
}
7473

7574
protected resolveDBFlags(): WebPowerSyncFlags {
76-
return _.merge(_.clone(DEFAULT_POWERSYNC_FLAGS), {
77-
ssrMode: this.isServerSide(),
78-
enableMultiTabs: this.options.flags?.enableMultiTabs
79-
});
75+
let flags = {
76+
...DEFAULT_POWERSYNC_FLAGS,
77+
ssrMode: this.isServerSide()
78+
};
79+
if (typeof this.options.flags?.enableMultiTabs != 'undefined') {
80+
flags.enableMultiTabs = this.options.flags.enableMultiTabs;
81+
}
82+
return flags;
8083
}
8184

8285
generateInstance(options: PowerSyncDatabaseOptions): AbstractPowerSyncDatabase {

packages/powersync-sdk-web/src/db/sync/SSRWebStreamingSyncImplementation.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import _ from 'lodash';
21
import {
32
AbstractStreamingSyncImplementation,
43
AbstractStreamingSyncImplementationOptions,

packages/powersync-sdk-web/src/db/sync/SharedWebStreamingSyncImplementation.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import _ from 'lodash';
21
import { v4 as uuid } from 'uuid';
32
import * as Comlink from 'comlink';
43
import {

packages/powersync-sdk-web/src/db/sync/WebStreamingSyncImplementation.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import _ from 'lodash';
21
import {
32
AbstractStreamingSyncImplementation,
43
AbstractStreamingSyncImplementationOptions,

packages/powersync-sdk-web/src/worker/db/open-db.ts

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as SQLite from '@journeyapps/wa-sqlite';
22
import '@journeyapps/wa-sqlite';
3-
import _ from 'lodash';
43
import * as Comlink from 'comlink';
54
import { v4 as uuid } from 'uuid';
65
import { QueryResult } from '@journeyapps/powersync-sdk-common';
@@ -93,21 +92,16 @@ export async function _openDB(dbFileName: string): Promise<DBWorkerInterface> {
9392
}
9493
}
9594

96-
const rows = _.chain(results)
97-
.filter(({ rows }) => !!rows.length)
98-
.flatMap(({ columns, rows }) =>
99-
_.map(rows, (row) =>
100-
_.reduce(
101-
columns,
102-
(out: Record<string, any>, key: string, index) => {
103-
out[key] = row[index];
104-
return out;
105-
},
106-
{}
107-
)
108-
)
109-
)
110-
.value();
95+
let rows: Record<string, any>[] = [];
96+
for (let resultset of results) {
97+
for (let row of resultset.rows) {
98+
let outRow: Record<string, any> = {};
99+
resultset.columns.forEach((key, index) => {
100+
outRow[key] = row[index];
101+
});
102+
rows.push(outRow);
103+
}
104+
}
111105

112106
const result = {
113107
insertId: sqlite3.last_insert_id(db),

0 commit comments

Comments
 (0)