Skip to content

Commit e095c7f

Browse files
committed
Migrate web package
1 parent d3b95ca commit e095c7f

32 files changed

Lines changed: 240 additions & 267 deletions

packages/common/src/utils/Logger.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,14 @@ export interface CreateLoggerOptions {
4545
*
4646
* @param options Options to configure a minimum severity of the logger or a prefix to make messages more recognizable.
4747
*/
48-
export function createPowerSyncLogger(options?: Partial<CreateLoggerOptions>): PowerSyncLogger {
48+
export function createPowerSyncLogger(options?: Partial<CreateLoggerOptions>): PowerSyncLogger & CreateLoggerOptions {
4949
const { prefix = 'PowerSync', minLevel = LogLevels.info } = options ?? {};
5050

5151
return {
52+
prefix,
53+
minLevel,
5254
log(level, ...message) {
53-
if (level < minLevel) return;
55+
if (level < this.minLevel) return;
5456

5557
let emitter = console.log;
5658
if (level >= LogLevels.error) {
@@ -59,7 +61,7 @@ export function createPowerSyncLogger(options?: Partial<CreateLoggerOptions>): P
5961
emitter = console.warn;
6062
}
6163

62-
emitter(prefix, ...message);
64+
emitter(this.prefix, ...message);
6365
}
6466
};
6567
}

packages/web/src/db/PowerSyncDatabase.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import {
1414
type BucketStorageAdapter,
1515
type PowerSyncBackendConnector,
1616
type PowerSyncCloseOptions,
17-
type RequiredAdditionalConnectionOptions
17+
type RequiredAdditionalConnectionOptions,
18+
LogLevels
1819
} from '@powersync/common';
1920
import { getNavigatorLocks } from '../shared/navigator.js';
2021
import { NAVIGATOR_TRIGGER_CLAIM_MANAGER } from './NavigatorTriggerClaimManager.js';
@@ -44,6 +45,13 @@ export interface WebPowerSyncFlags extends WebSQLFlags {
4445
* instances before the window unloads
4546
*/
4647
externallyUnload?: boolean;
48+
49+
/**
50+
* The log level for database workers.
51+
*
52+
* Defaults to {@link LogLevels.info}.
53+
*/
54+
databaseWorkerLogLevel?: number;
4755
}
4856

4957
type WithWebFlags<Base> = Base & { flags?: WebPowerSyncFlags };
@@ -56,6 +64,13 @@ export interface WebSyncOptions {
5664
* or a factory method that returns a worker.
5765
*/
5866
worker?: string | URL | ((options: ResolvedWebSQLOpenOptions) => SharedWorker);
67+
68+
/**
69+
* The log level for logs from the sync worker.
70+
*
71+
* Defaults to {@link LogLevels.info}.
72+
*/
73+
logLevel?: number;
5974
}
6075

6176
type WithWebSyncOptions<Base> = Base & {
@@ -86,7 +101,8 @@ export type WebPowerSyncDatabaseOptions = WithWebSyncOptions<WithWebFlags<PowerS
86101

87102
export const DEFAULT_POWERSYNC_FLAGS: Required<WebPowerSyncFlags> = {
88103
...DEFAULT_WEB_SQL_FLAGS,
89-
externallyUnload: false
104+
externallyUnload: false,
105+
databaseWorkerLogLevel: LogLevels.info
90106
};
91107

92108
export const resolveWebPowerSyncFlags = (flags?: WebPowerSyncFlags): Required<WebPowerSyncFlags> => {
@@ -171,10 +187,13 @@ export class PowerSyncDatabase extends AbstractPowerSyncDatabase {
171187
}
172188

173189
protected openDBAdapter(options: WebPowerSyncDatabaseOptionsWithSettings): DBAdapter {
190+
const resolvedFlags = resolveWebPowerSyncFlags(options.flags);
174191
const defaultFactory = new WASQLiteOpenFactory({
175192
...options.database,
176-
flags: resolveWebPowerSyncFlags(options.flags),
177-
encryptionKey: options.encryptionKey
193+
flags: resolvedFlags,
194+
encryptionKey: options.encryptionKey,
195+
logger: this.logger,
196+
logLevel: resolvedFlags.databaseWorkerLogLevel
178197
});
179198
return defaultFactory.openDB();
180199
}
@@ -206,7 +225,7 @@ export class PowerSyncDatabase extends AbstractPowerSyncDatabase {
206225
}
207226

208227
protected generateBucketStorageAdapter(): BucketStorageAdapter {
209-
return new SqliteBucketStorage(this.database);
228+
return new SqliteBucketStorage(this.database, this.logger);
210229
}
211230

212231
protected async runExclusive<T>(cb: () => Promise<T>) {
@@ -245,11 +264,12 @@ export class PowerSyncDatabase extends AbstractPowerSyncDatabase {
245264
Logs for shared sync worker will only be available in the shared worker context
246265
`;
247266
const logger = this.options.logger;
248-
logger ? logger.warn(warning) : console.warn(warning);
267+
logger ? logger.log(LogLevels.warn, warning) : console.warn(warning);
249268
}
250269
return new SharedWebStreamingSyncImplementation({
251270
...syncOptions,
252-
db: this.database as WebDBAdapter // This should always be the case
271+
db: this.database as WebDBAdapter, // This should always be the case
272+
logLevel: this.options.sync?.logLevel ?? LogLevels.info
253273
});
254274
default:
255275
return new WebStreamingSyncImplementation(syncOptions);

packages/web/src/db/adapters/wa-sqlite/DatabaseServer.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { ILogger } from '@powersync/common';
1+
import { LogLevels, PowerSyncLogger } from '@powersync/common';
22
import { ConcurrentSqliteConnection, ConnectionLeaseToken } from './ConcurrentConnection.js';
33
import { RawQueryResult } from './RawSqliteConnection.js';
44

55
export interface DatabaseServerOptions {
66
inner: ConcurrentSqliteConnection;
77
onClose: () => void;
8-
logger: ILogger;
8+
logger: PowerSyncLogger;
99
}
1010

1111
/**
@@ -85,7 +85,7 @@ export class DatabaseServer {
8585

8686
// If the client holds a connection lease it hasn't returned, return that now.
8787
for (const { lease } of connectionLeases.values()) {
88-
this.#logger.debug(`Closing connection lease that hasn't been returned.`);
88+
this.#logger.log(LogLevels.debug, `Closing connection lease that hasn't been returned.`);
8989
await lease.returnLease();
9090
}
9191

@@ -94,7 +94,7 @@ export class DatabaseServer {
9494
if (this.#activeClients.size == 0) {
9595
await this.forceClose();
9696
} else {
97-
this.#logger.debug('Keeping underlying connection active since its used by other clients.');
97+
this.#logger.log(LogLevels.debug, 'Keeping underlying connection active since its used by other clients.');
9898
}
9999
}
100100
};
@@ -169,7 +169,7 @@ export class DatabaseServer {
169169
}
170170

171171
async forceClose() {
172-
this.#logger.debug(`Closing connection to ${this.#inner.options}.`);
172+
this.#logger.log(LogLevels.debug, `Closing connection to ${this.#inner.options}.`);
173173
const connection = this.#inner;
174174
this.#options.onClose();
175175
this.#updateBroadcastChannel.close();

packages/web/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createLogger, DBAdapter, ILogger, SQLOpenFactory, type ILogLevel } from '@powersync/common';
1+
import { createPowerSyncLogger, DBAdapter, LogLevels, PowerSyncLogger, SQLOpenFactory } from '@powersync/common';
22
import * as Comlink from 'comlink';
33
import { openWorkerDatabasePort, resolveWorkerDatabasePortFactory } from '../../../worker/db/open-worker-database.js';
44
import {
@@ -29,6 +29,13 @@ export interface WASQLiteOpenFactoryOptions extends WebSQLOpenFactoryOptions {
2929
* Defaults to 1.
3030
*/
3131
additionalReaders?: number;
32+
33+
/**
34+
* The {@link LogLevels} value to use for logs in the worker.
35+
*/
36+
logLevel: number;
37+
38+
logger: PowerSyncLogger;
3239
}
3340

3441
export interface ResolvedWASQLiteOpenFactoryOptions extends ResolvedWebSQLOpenOptions {
@@ -41,7 +48,7 @@ export interface ResolvedWASQLiteOpenFactoryOptions extends ResolvedWebSQLOpenOp
4148
}
4249

4350
export interface WorkerDBOpenerOptions extends ResolvedWASQLiteOpenFactoryOptions {
44-
logLevel: ILogLevel;
51+
logLevel: number;
4552
/**
4653
* A lock that is currently held by the client. When the lock is returned, we know the client is gone and that we need
4754
* to clean up resources.
@@ -54,12 +61,12 @@ export interface WorkerDBOpenerOptions extends ResolvedWASQLiteOpenFactoryOption
5461
*/
5562
export class WASQLiteOpenFactory implements SQLOpenFactory {
5663
private resolvedFlags: ResolvedWebSQLFlags;
57-
private logger: ILogger;
64+
private logger: PowerSyncLogger;
5865

5966
constructor(private options: WASQLiteOpenFactoryOptions) {
6067
assertValidWASQLiteOpenFactoryOptions(options);
6168
this.resolvedFlags = resolveWebSQLFlags(options.flags);
62-
this.logger = options.logger ?? createLogger(`WASQLiteOpenFactory - ${this.options.dbFilename}`);
69+
this.logger = options.logger;
6370
}
6471

6572
get waOptions(): WASQLiteOpenFactoryOptions {
@@ -77,7 +84,8 @@ export class WASQLiteOpenFactory implements SQLOpenFactory {
7784
} = this;
7885
if (ssrMode) {
7986
if (!disableSSRWarning) {
80-
this.logger.warn(
87+
this.logger.log(
88+
LogLevels.warn,
8189
`
8290
Running PowerSync in SSR mode.
8391
Only empty query results will be returned.
@@ -89,7 +97,8 @@ export class WASQLiteOpenFactory implements SQLOpenFactory {
8997
}
9098

9199
if (!enableMultiTabs) {
92-
this.logger.warn(
100+
this.logger.log(
101+
LogLevels.warn,
93102
'Multiple tab support is not enabled. Using this site across multiple tabs may not function correctly.'
94103
);
95104
}
@@ -107,7 +116,7 @@ export class WASQLiteOpenFactory implements SQLOpenFactory {
107116
} = this.waOptions;
108117

109118
if (!enableMultiTabs) {
110-
this.logger.warn('Multiple tabs are not enabled in this browser');
119+
this.logger.log(LogLevels.warn, 'Multiple tabs are not enabled in this browser');
111120
}
112121

113122
const resolveOptions = (isReadOnly: boolean): ResolvedWASQLiteOpenFactoryOptions => ({
@@ -149,7 +158,7 @@ export class WASQLiteOpenFactory implements SQLOpenFactory {
149158
const closeSignal = new AbortController();
150159
const connection = await source.connect({
151160
...resolvedOptions,
152-
logLevel: this.logger.getLevel(),
161+
logLevel: this.options.logLevel,
153162
lockName: await generateTabCloseSignal(closeSignal.signal)
154163
});
155164
const clientOptions = {
@@ -190,7 +199,7 @@ export class WASQLiteOpenFactory implements SQLOpenFactory {
190199
requiresPersistentTriggers = true;
191200

192201
const resolvedOptions = resolveOptions(false);
193-
const connection = await localServer.openConnectionLocally(resolvedOptions);
202+
const connection = await localServer.openConnectionLocally(this.logger, resolvedOptions);
194203
client = new DatabaseClient(
195204
{ connection, source: null, remoteCanCloseUnexpectedly: false },
196205
{

packages/web/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { AbstractPowerSyncDatabase, DBAdapter, PowerSyncDatabaseOptions } from '@powersync/common';
1+
import {
2+
AbstractPowerSyncDatabase,
3+
createPowerSyncLogger,
4+
DBAdapter,
5+
LogLevels,
6+
PowerSyncDatabaseOptions
7+
} from '@powersync/common';
28
import { PowerSyncDatabase } from '../../../db/PowerSyncDatabase.js';
39
import { AbstractWebPowerSyncDatabaseOpenFactory } from '../AbstractWebPowerSyncDatabaseOpenFactory.js';
410
import { WASQLiteOpenFactory } from './WASQLiteOpenFactory.js';
@@ -14,7 +20,11 @@ import { WASQLiteOpenFactory } from './WASQLiteOpenFactory.js';
1420
*/
1521
export class WASQLitePowerSyncDatabaseOpenFactory extends AbstractWebPowerSyncDatabaseOpenFactory {
1622
protected openDB(): DBAdapter {
17-
const factory = new WASQLiteOpenFactory(this.options);
23+
const factory = new WASQLiteOpenFactory({
24+
logger: createPowerSyncLogger(),
25+
logLevel: LogLevels.info,
26+
...this.options
27+
});
1828
return factory.openDB();
1929
}
2030

packages/web/src/db/adapters/web-sql-flags.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type ILogger, SQLOpenOptions } from '@powersync/common';
1+
import { type PowerSyncLogger, SQLOpenOptions } from '@powersync/common';
22

33
/**
44
* Common settings used when creating SQL connections on web.
@@ -82,7 +82,7 @@ export interface WebSQLOpenFactoryOptions extends SQLOpenOptions {
8282
*/
8383
workerPort?: MessagePort;
8484

85-
logger?: ILogger;
85+
logger?: PowerSyncLogger;
8686

8787
/**
8888
* Where to store SQLite temporary files. Defaults to 'MEMORY'.

packages/web/src/db/sync/SharedWebStreamingSyncImplementation.ts

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
SyncStatusOptions
66
} from '@powersync/common';
77
import * as Comlink from 'comlink';
8-
import { getNavigatorLocks } from '../../shared/navigator.js';
98
import { AbstractSharedSyncClientProvider } from '../../worker/sync/AbstractSharedSyncClientProvider.js';
109
import { ManualSharedSyncPayload, SharedSyncClientEvent } from '../../worker/sync/SharedSyncImplementation.js';
1110
import { WorkerClient } from '../../worker/sync/WorkerClient.js';
@@ -68,33 +67,13 @@ class SharedSyncClientProvider extends AbstractSharedSyncClientProvider {
6867
return this.options.logger;
6968
}
7069

71-
trace(...x: any[]): void {
72-
this.logger?.trace(...x);
73-
}
74-
debug(...x: any[]): void {
75-
this.logger?.debug(...x);
76-
}
77-
info(...x: any[]): void {
78-
this.logger?.info(...x);
79-
}
80-
log(...x: any[]): void {
81-
this.logger?.log(...x);
82-
}
83-
warn(...x: any[]): void {
84-
this.logger?.warn(...x);
85-
}
86-
error(...x: any[]): void {
87-
this.logger?.error(...x);
88-
}
89-
time(label: string): void {
90-
this.logger?.time(label);
91-
}
92-
timeEnd(label: string): void {
93-
this.logger?.timeEnd(label);
70+
log(level: number, ...message: any[]): void {
71+
this.logger?.log(level, message);
9472
}
9573
}
9674

9775
export interface SharedWebStreamingSyncImplementationOptions extends WebStreamingSyncImplementationOptions {
76+
logLevel: number;
9877
db: WebDBAdapter;
9978
}
10079

@@ -109,10 +88,12 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
10988
protected isInitialized: Promise<void>;
11089
protected dbAdapter: WebDBAdapter;
11190
private abortOnClose = new AbortController();
91+
private logLevel: number;
11292

11393
constructor(options: SharedWebStreamingSyncImplementationOptions) {
11494
super(options);
11595
this.dbAdapter = options.db;
96+
this.logLevel = options.logLevel;
11697
/**
11798
* Configure or connect to the shared sync worker.
11899
* This worker will manage all syncing operations remotely.
@@ -165,7 +146,7 @@ export class SharedWebStreamingSyncImplementation extends WebStreamingSyncImplem
165146
*/
166147
Comlink.expose(this.clientProvider, this.messagePort);
167148

168-
this.syncManager.setLogLevel(this.logger.getLevel());
149+
this.syncManager.setLogLevel(this.logLevel);
169150

170151
this.triggerCrudUpload = this.syncManager.triggerCrudUpload;
171152

packages/web/src/db/sync/WebRemote.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import {
22
AbstractRemote,
33
AbstractRemoteOptions,
4-
DEFAULT_REMOTE_LOGGER,
54
FetchImplementation,
65
FetchImplementationProvider,
7-
ILogger,
6+
LogLevels,
7+
PowerSyncLogger,
88
RemoteConnector
99
} from '@powersync/common';
1010

@@ -22,7 +22,7 @@ class WebFetchProvider extends FetchImplementationProvider {
2222
export class WebRemote extends AbstractRemote {
2323
constructor(
2424
protected connector: RemoteConnector,
25-
protected logger: ILogger = DEFAULT_REMOTE_LOGGER,
25+
protected logger: PowerSyncLogger,
2626
options?: Partial<AbstractRemoteOptions>
2727
) {
2828
super(connector, logger, {
@@ -36,7 +36,7 @@ export class WebRemote extends AbstractRemote {
3636
try {
3737
ua.push(...getUserAgentInfo());
3838
} catch (e) {
39-
this.logger.warn('Failed to get user agent info', e);
39+
this.logger.log(LogLevels.warn, 'Failed to get user agent info', e);
4040
}
4141
return ua.join(' ');
4242
}

0 commit comments

Comments
 (0)