(config: PowerSyncCollectionConfig<TTable, TSchema>)
| 224 | */ |
| 225 | |
| 226 | export function powerSyncCollectionOptions< |
| 227 | TTable extends Table, |
| 228 | TSchema extends StandardSchemaV1<any> = never, |
| 229 | >(config: PowerSyncCollectionConfig<TTable, TSchema>) { |
| 230 | const { |
| 231 | database, |
| 232 | table, |
| 233 | schema: inputSchema, |
| 234 | syncBatchSize = DEFAULT_BATCH_SIZE, |
| 235 | syncMode = 'eager', |
| 236 | ...restConfig |
| 237 | } = config |
| 238 | |
| 239 | const deserializationSchema = |
| 240 | `deserializationSchema` in config ? config.deserializationSchema : null |
| 241 | const serializer = `serializer` in config ? config.serializer : undefined |
| 242 | const onDeserializationError = |
| 243 | `onDeserializationError` in config |
| 244 | ? config.onDeserializationError |
| 245 | : undefined |
| 246 | |
| 247 | // The SQLite table type |
| 248 | type TableType = ExtractedTable<TTable> |
| 249 | |
| 250 | // The collection output type |
| 251 | type OutputType = InferPowerSyncOutputType<TTable, TSchema> |
| 252 | |
| 253 | const { viewName, trackMetadata: metadataIsTracked } = table |
| 254 | |
| 255 | /** |
| 256 | * Deserializes data from the incoming sync stream |
| 257 | */ |
| 258 | const deserializeSyncRow = (value: TableType): OutputType => { |
| 259 | const validationSchema = deserializationSchema || schema |
| 260 | const validation = validationSchema[`~standard`].validate(value) |
| 261 | if (`value` in validation) { |
| 262 | return validation.value |
| 263 | } else if (`issues` in validation) { |
| 264 | const issueMessage = `Failed to validate incoming data for ${viewName}. Issues: ${validation.issues.map((issue) => `${issue.path} - ${issue.message}`)}` |
| 265 | database.logger.error(issueMessage) |
| 266 | onDeserializationError!(validation) |
| 267 | throw new Error(issueMessage) |
| 268 | } else { |
| 269 | const unknownErrorMessage = `Unknown deserialization error for ${viewName}` |
| 270 | database.logger.error(unknownErrorMessage) |
| 271 | onDeserializationError!({ issues: [{ message: unknownErrorMessage }] }) |
| 272 | throw new Error(unknownErrorMessage) |
| 273 | } |
| 274 | } |
| 275 | |
| 276 | // We can do basic runtime validations for columns if not explicit schema has been provided |
| 277 | const schema = inputSchema ?? (convertTableToSchema(table) as TSchema) |
| 278 | /** |
| 279 | * The onInsert, onUpdate, and onDelete handlers should only return |
| 280 | * after we have written the changes to TanStack DB. |
| 281 | * We currently only write to TanStack DB from a diff trigger. |
| 282 | * We wait for the diff trigger to observe the change, |
| 283 | * and only then return from the on[X] handlers. |
searching dependent graphs…