Skip to content

Commit

Permalink
Install expo-sqlite dep
Browse files Browse the repository at this point in the history
  • Loading branch information
catalinmiron committed Dec 20, 2024
1 parent a790fd4 commit bbac10c
Show file tree
Hide file tree
Showing 3 changed files with 17,193 additions and 16,330 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.2",
"expect-type": "^0.19.0",
"expo-sqlite": "^15.0.3",
"fake-indexeddb": "^6.0.0",
"firebase": "^10.12.2",
"jest": "^29.7.0",
Expand Down Expand Up @@ -139,4 +140,4 @@
"@commitlint/config-conventional"
]
}
}
}
210 changes: 97 additions & 113 deletions src/persist-plugins/expo-sqlite.ts
Original file line number Diff line number Diff line change
@@ -1,134 +1,118 @@
import type { Change } from "@legendapp/state";
import { applyChanges,internal,isArray } from "@legendapp/state";
import type { Change } from '@legendapp/state';
import { applyChanges, internal, isArray } from '@legendapp/state';
import type {
ObservablePersistPlugin,
ObservablePersistPluginOptions,
ObservablePersistSQLiteStoragePluginOptions,
PersistMetadata,
} from "@legendapp/state/sync";
import type { SQLiteStorage as SQLiteStorageStatic } from "expo-sqlite/kv-store";
ObservablePersistPlugin,
ObservablePersistPluginOptions,
ObservablePersistSQLiteStoragePluginOptions,
PersistMetadata,
} from '@legendapp/state/sync';
import type { SQLiteStorage as SQLiteStorageStatic } from 'expo-sqlite/kv-store';

const MetadataSuffix = "__m";
const MetadataSuffix = '__m';

let SQLiteStorage: SQLiteStorageStatic;

const { safeParse, safeStringify } = internal;

export class ObservablePersistSQLiteStorage implements ObservablePersistPlugin {
private data: Record<string, any> = {};
private configuration: ObservablePersistSQLiteStoragePluginOptions;
private data: Record<string, any> = {};
private configuration: ObservablePersistSQLiteStoragePluginOptions;

constructor(configuration: ObservablePersistSQLiteStoragePluginOptions) {
this.configuration = configuration;
}
public async initialize(configOptions: ObservablePersistPluginOptions) {
const storageConfig = this.configuration || configOptions.sQLiteStorage;
constructor(configuration: ObservablePersistSQLiteStoragePluginOptions) {
this.configuration = configuration;
}
public async initialize(configOptions: ObservablePersistPluginOptions) {
const storageConfig = this.configuration || configOptions.sQLiteStorage;

let tables: readonly string[] = [];
if (storageConfig) {
SQLiteStorage = storageConfig.SQLiteStorage;
const { preload } = storageConfig;
try {
if (preload === true) {
// If preloadAllKeys, load all keys and preload tables on startup
tables = await SQLiteStorage.getAllKeys();
} else if (isArray(preload)) {
// If preloadKeys, preload load the tables on startup
const metadataTables = preload.map((table) =>
table.endsWith(MetadataSuffix) ? undefined : table + MetadataSuffix
);
tables = [
...preload,
...(metadataTables.filter(Boolean) as string[]),
];
}
if (tables) {
const values = await SQLiteStorage.multiGet(tables);
let tables: readonly string[] = [];
if (storageConfig) {
SQLiteStorage = storageConfig.SQLiteStorage;
const { preload } = storageConfig;
try {
if (preload === true) {
// If preloadAllKeys, load all keys and preload tables on startup
tables = await SQLiteStorage.getAllKeys();
} else if (isArray(preload)) {
// If preloadKeys, preload load the tables on startup
const metadataTables = preload.map((table) =>
table.endsWith(MetadataSuffix) ? undefined : table + MetadataSuffix,
);
tables = [...preload, ...(metadataTables.filter(Boolean) as string[])];
}
if (tables) {
const values = await SQLiteStorage.multiGet(tables);

values.forEach(([table, value]) => {
this.data[table] = value ? safeParse(value) : undefined;
});
values.forEach(([table, value]) => {
this.data[table] = value ? safeParse(value) : undefined;
});
}
} catch (e) {
console.error('[legend-state] ObservablePersistSQLiteStorage failed to initialize', e);
}
} else {
console.error('[legend-state] Missing sQLiteStorage configuration');
}
}
public loadTable(table: string): void | Promise<void> {
if (this.data[table] === undefined) {
return SQLiteStorage.multiGet([table, table + MetadataSuffix])
.then((values) => {
try {
values.forEach(([table, value]) => {
this.data[table] = value ? safeParse(value) : undefined;
});
} catch (err) {
console.error('[legend-state] ObservablePersistLocalSQLiteStorage failed to parse', table, err);
}
})
.catch((err: Error) => {
if (err?.message !== 'window is not defined') {
console.error('[legend-state] SQLiteStorage.multiGet failed', table, err);
}
});
}
} catch (e) {
console.error(
"[legend-state] ObservablePersistSQLiteStorage failed to initialize",
e
);
}
} else {
console.error("[legend-state] Missing sQLiteStorage configuration");
}
}
public loadTable(table: string): void | Promise<void> {
if (this.data[table] === undefined) {
return SQLiteStorage.multiGet([table, table + MetadataSuffix])
.then((values) => {
try {
values.forEach(([table, value]) => {
this.data[table] = value ? safeParse(value) : undefined;
});
} catch (err) {
console.error(
"[legend-state] ObservablePersistLocalSQLiteStorage failed to parse",
table,
err
);
}
})
.catch((err: Error) => {
if (err?.message !== "window is not defined") {
console.error(
"[legend-state] SQLiteStorage.multiGet failed",
table,
err
);
}
});
// Gets
public getTable(table: string, init: object) {
return this.data[table] ?? init ?? {};
}
}
// Gets
public getTable(table: string, init: object) {
return this.data[table] ?? init ?? {};
}
public getMetadata(table: string): PersistMetadata {
return this.getTable(table + MetadataSuffix, {});
}
// Sets
public set(table: string, changes: Change[]): Promise<void> {
if (!this.data[table]) {
this.data[table] = {};
public getMetadata(table: string): PersistMetadata {
return this.getTable(table + MetadataSuffix, {});
}
// Sets
public set(table: string, changes: Change[]): Promise<void> {
if (!this.data[table]) {
this.data[table] = {};
}

this.data[table] = applyChanges(this.data[table], changes);
return this.save(table);
}
public setMetadata(table: string, metadata: PersistMetadata) {
return this.setValue(table + MetadataSuffix, metadata);
}
public async deleteTable(table: string) {
return SQLiteStorage.removeItem(table);
}
public deleteMetadata(table: string) {
return this.deleteTable(table + MetadataSuffix);
}
// Private
private async setValue(table: string, value: any) {
this.data[table] = value;
await this.save(table);
}
private async save(table: string) {
const v = this.data[table];
this.data[table] = applyChanges(this.data[table], changes);
return this.save(table);
}
public setMetadata(table: string, metadata: PersistMetadata) {
return this.setValue(table + MetadataSuffix, metadata);
}
public async deleteTable(table: string) {
return SQLiteStorage.removeItem(table);
}
public deleteMetadata(table: string) {
return this.deleteTable(table + MetadataSuffix);
}
// Private
private async setValue(table: string, value: any) {
this.data[table] = value;
await this.save(table);
}
private async save(table: string) {
const v = this.data[table];

if (v !== undefined && v !== null) {
return SQLiteStorage.setItem(table, safeStringify(v));
} else {
return SQLiteStorage.removeItem(table);
if (v !== undefined && v !== null) {
return SQLiteStorage.setItem(table, safeStringify(v));
} else {
return SQLiteStorage.removeItem(table);
}
}
}
}

export function observablePersistSQLiteStorage(
configuration: ObservablePersistSQLiteStoragePluginOptions
) {
return new ObservablePersistSQLiteStorage(configuration);
export function observablePersistSQLiteStorage(configuration: ObservablePersistSQLiteStoragePluginOptions) {
return new ObservablePersistSQLiteStorage(configuration);
}
Loading

0 comments on commit bbac10c

Please sign in to comment.