@@ -3,19 +3,17 @@ import { DEFAULT_BATCH_SIZE } from "./definitions"
33import { asPowerSyncRecord , mapOperation } from "./helpers"
44import { PendingOperationStore } from "./PendingOperationStore"
55import { PowerSyncTransactor } from "./PowerSyncTransactor"
6- import type { TriggerDiffRecord } from "@powersync/common"
7- import type { StandardSchemaV1 } from "@standard-schema/spec"
8- import type {
9- CollectionConfig ,
10- InferSchemaOutput ,
11- SyncConfig ,
12- } from "@tanstack/db"
6+ import { convertTableToSchema } from "./schema"
7+ import type { ExtractedTable } from "./helpers"
8+ import type { PendingOperation } from "./PendingOperationStore"
139import type {
1410 EnhancedPowerSyncCollectionConfig ,
1511 PowerSyncCollectionConfig ,
1612 PowerSyncCollectionUtils ,
1713} from "./definitions"
18- import type { PendingOperation } from "./PendingOperationStore"
14+ import type { CollectionConfig , SyncConfig } from "@tanstack/db"
15+ import type { StandardSchemaV1 } from "@standard-schema/spec"
16+ import type { ColumnsType , Table , TriggerDiffRecord } from "@powersync/common"
1917
2018/**
2119 * Creates PowerSync collection options for use with a standard Collection
@@ -42,18 +40,19 @@ import type { PendingOperation } from "./PendingOperationStore"
4240 * const collection = createCollection(
4341 * powerSyncCollectionOptions({
4442 * database: db,
45- * tableName: " documents" ,
46- * schema: APP_SCHEMA,
43+ * table: APP_SCHEMA.props. documents,
44+ * schema: TODO
4745 * })
4846 * )
4947 * ```
5048 */
51- export function powerSyncCollectionOptions < T extends StandardSchemaV1 > (
52- config : PowerSyncCollectionConfig < InferSchemaOutput < T > , T >
53- ) : CollectionConfig < InferSchemaOutput < T > , string , T > & {
54- schema : T
55- utils : PowerSyncCollectionUtils
56- }
49+ // TODO!!!
50+ // export function powerSyncCollectionOptions<T extends StandardSchemaV1>(
51+ // config: PowerSyncCollectionConfig<InferSchemaOutput<T>, T>
52+ // ): CollectionConfig<InferSchemaOutput<T>, string, T> & {
53+ // schema: T
54+ // utils: PowerSyncCollectionUtils
55+ // }
5756
5857/**
5958 * Creates a PowerSync collection configuration without schema validation.
@@ -76,18 +75,20 @@ export function powerSyncCollectionOptions<T extends StandardSchemaV1>(
7675 * })
7776 *
7877 * const collection = createCollection(
79- * powerSyncCollectionOptions<Document> ({
78+ * powerSyncCollectionOptions({
8079 * database: db,
81- * tableName: " documents",
80+ * table: APP_SCHEMA.props. documents
8281 * })
8382 * )
8483 * ```
8584 */
86- export function powerSyncCollectionOptions < T extends object > (
87- config : PowerSyncCollectionConfig < T > & {
85+ export function powerSyncCollectionOptions <
86+ TableType extends Table < ColumnsType > = Table < ColumnsType > ,
87+ > (
88+ config : PowerSyncCollectionConfig < TableType > & {
8889 schema ?: never
8990 }
90- ) : CollectionConfig < T , string > & {
91+ ) : CollectionConfig < ExtractedTable < TableType [ `columnMap` ] > , string > & {
9192 schema ?: never
9293 utils : PowerSyncCollectionUtils
9394}
@@ -96,18 +97,24 @@ export function powerSyncCollectionOptions<T extends object>(
9697 * Implementation of powerSyncCollectionOptions that handles both schema and non-schema configurations.
9798 */
9899export function powerSyncCollectionOptions <
99- T extends object = Record < string , unknown > ,
100+ TableType extends Table < ColumnsType > = Table < ColumnsType > ,
100101 TSchema extends StandardSchemaV1 = never ,
101102> (
102- config : PowerSyncCollectionConfig < T , TSchema >
103- ) : EnhancedPowerSyncCollectionConfig < T , TSchema > {
103+ config : PowerSyncCollectionConfig < TableType , TSchema >
104+ ) : EnhancedPowerSyncCollectionConfig < TableType , TSchema > {
104105 const {
105106 database,
106- tableName,
107+ table,
108+ schema : inputSchema ,
107109 syncBatchSize = DEFAULT_BATCH_SIZE ,
108110 ...restConfig
109111 } = config
110112
113+ type RecordType = ExtractedTable < TableType [ `columnMap`] >
114+ const { viewName } = table
115+
116+ // We can do basic runtime validations for columns if not explicit schema has been provided
117+ const schema = inputSchema ?? ( convertTableToSchema ( table ) as TSchema )
111118 /**
112119 * The onInsert, onUpdate, onDelete handlers should only return
113120 * after we have written the changes to Tanstack DB.
@@ -120,13 +127,13 @@ export function powerSyncCollectionOptions<
120127 */
121128 const pendingOperationStore = PendingOperationStore . GLOBAL
122129 // Keep the tracked table unique in case of multiple tabs.
123- const trackedTableName = `__${ tableName } _tracking_${ Math . floor (
130+ const trackedTableName = `__${ viewName } _tracking_${ Math . floor (
124131 Math . random ( ) * 0xffffffff
125132 )
126133 . toString ( 16 )
127134 . padStart ( 8 , `0` ) } `
128135
129- const transactor = new PowerSyncTransactor < T > ( {
136+ const transactor = new PowerSyncTransactor < RecordType > ( {
130137 database,
131138 } )
132139
@@ -135,15 +142,15 @@ export function powerSyncCollectionOptions<
135142 * Notice that this describes the Sync between the local SQLite table
136143 * and the in-memory tanstack-db collection.
137144 */
138- const sync : SyncConfig < T , string > = {
145+ const sync : SyncConfig < RecordType , string > = {
139146 sync : ( params ) => {
140147 const { begin, write, commit, markReady } = params
141148 const abortController = new AbortController ( )
142149
143150 // The sync function needs to be synchronous
144151 async function start ( ) {
145152 database . logger . info (
146- `Sync is starting for ${ tableName } into ${ trackedTableName } `
153+ `Sync is starting for ${ viewName } into ${ trackedTableName } `
147154 )
148155 database . onChangeWithCallback (
149156 {
@@ -175,7 +182,7 @@ export function powerSyncCollectionOptions<
175182 id,
176183 operation,
177184 timestamp,
178- tableName,
185+ tableName : viewName ,
179186 } )
180187 }
181188
@@ -201,7 +208,7 @@ export function powerSyncCollectionOptions<
201208 )
202209
203210 const disposeTracking = await database . triggers . createDiffTrigger ( {
204- source : tableName ,
211+ source : viewName ,
205212 destination : trackedTableName ,
206213 when : {
207214 [ DiffTriggerOperation . INSERT ] : `TRUE` ,
@@ -214,8 +221,8 @@ export function powerSyncCollectionOptions<
214221 let cursor = 0
215222 while ( currentBatchCount == syncBatchSize ) {
216223 begin ( )
217- const batchItems = await context . getAll < T > (
218- sanitizeSQL `SELECT * FROM ${ tableName } LIMIT ? OFFSET ?` ,
224+ const batchItems = await context . getAll < RecordType > (
225+ sanitizeSQL `SELECT * FROM ${ viewName } LIMIT ? OFFSET ?` ,
219226 [ syncBatchSize , cursor ]
220227 )
221228 currentBatchCount = batchItems . length
@@ -230,7 +237,7 @@ export function powerSyncCollectionOptions<
230237 }
231238 markReady ( )
232239 database . logger . info (
233- `Sync is ready for ${ tableName } into ${ trackedTableName } `
240+ `Sync is ready for ${ viewName } into ${ trackedTableName } `
234241 )
235242 } ,
236243 } ,
@@ -252,14 +259,14 @@ export function powerSyncCollectionOptions<
252259
253260 start ( ) . catch ( ( error ) =>
254261 database . logger . error (
255- `Could not start syncing process for ${ tableName } into ${ trackedTableName } ` ,
262+ `Could not start syncing process for ${ viewName } into ${ trackedTableName } ` ,
256263 error
257264 )
258265 )
259266
260267 return ( ) => {
261268 database . logger . info (
262- `Sync has been stopped for ${ tableName } into ${ trackedTableName } `
269+ `Sync has been stopped for ${ viewName } into ${ trackedTableName } `
263270 )
264271 abortController . abort ( )
265272 }
@@ -268,16 +275,18 @@ export function powerSyncCollectionOptions<
268275 getSyncMetadata : undefined ,
269276 }
270277
271- const getKey = ( record : T ) => asPowerSyncRecord ( record ) . id
278+ const getKey = ( record : RecordType ) => asPowerSyncRecord ( record ) . id
272279
273- const outputConfig : EnhancedPowerSyncCollectionConfig < T , TSchema > = {
280+ const outputConfig : EnhancedPowerSyncCollectionConfig < TableType , TSchema > = {
274281 ...restConfig ,
282+ schema,
275283 getKey,
276284 // Syncing should start immediately since we need to monitor the changes for mutations
277285 startSync : true ,
278286 sync,
279287 onInsert : async ( params ) => {
280288 // The transaction here should only ever contain a single insert mutation
289+ params . transaction
281290 return await transactor . applyTransaction ( params . transaction )
282291 } ,
283292 onUpdate : async ( params ) => {
@@ -290,7 +299,7 @@ export function powerSyncCollectionOptions<
290299 } ,
291300 utils : {
292301 getMeta : ( ) => ( {
293- tableName,
302+ tableName : viewName ,
294303 trackedTableName,
295304 } ) ,
296305 } ,
0 commit comments